Author: gdusbabek
Date: Tue Feb 23 21:48:31 2010
New Revision: 915533

URL: http://svn.apache.org/viewvc?rev=915533&view=rev
Log:
Refactor DatabaseDescriptor to isolate the code that establishes the keyspaces 
and column families. Patch by Gary Dusbabek, reviewed by Eric Evans.  
CASSANDRA-819

Added:
    
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java
Modified:
    
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
    
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
    
incubator/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java
    
incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java
    
incubator/cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java
    
incubator/cassandra/trunk/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
    
incubator/cassandra/trunk/test/unit/org/apache/cassandra/service/AntiEntropyServiceTest.java

Modified: 
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
URL: 
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java?rev=915533&r1=915532&r2=915533&view=diff
==============================================================================
--- 
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java 
(original)
+++ 
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java 
Tue Feb 23 21:48:31 2010
@@ -19,15 +19,36 @@
 package org.apache.cassandra.config;
 
 import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.utils.FBUtilities;
 
-public class CFMetaData
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public final class CFMetaData
 {
-    public String tableName;            // name of table which has this column 
family
-    public String cfName;               // name of the column family
-    public String columnType;           // type: super, standard, etc.
-    public AbstractType comparator;       // name sorted, time stamp sorted 
etc.
-    public AbstractType subcolumnComparator; // like comparator, for 
supercolumns
-    public String comment; // for humans only
+    public final String tableName;            // name of table which has this 
column family
+    public final String cfName;               // name of the column family
+    public final String columnType;           // type: super, standard, etc.
+    public final AbstractType comparator;       // name sorted, time stamp 
sorted etc.
+    public final AbstractType subcolumnComparator; // like comparator, for 
supercolumns
+    public final String comment; // for humans only
+    public final double rowCacheSize; // default 0
+    public final double keysCachedFraction; // default 0.01
+
+    CFMetaData(String tableName, String cfName, String columnType, 
AbstractType comparator, AbstractType subcolumnComparator, String comment, 
double rowCacheSize, double keysCachedFraction)
+    {
+        this.tableName = tableName;
+        this.cfName = cfName;
+        this.columnType = columnType;
+        this.comparator = comparator;
+        this.subcolumnComparator = subcolumnComparator;
+        this.comment = comment;
+        this.rowCacheSize = rowCacheSize;
+        this.keysCachedFraction = keysCachedFraction;
+    }
 
     // a quick and dirty pretty printer for describing the column family...
     public String pretty()
@@ -36,4 +57,70 @@
                + "Column Family Type: " + columnType + "\n"
                + "Columns Sorted By: " + comparator + "\n";
     }
+
+    public static byte[] serialize(CFMetaData cfm) throws IOException
+    {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        DataOutputStream dout = new DataOutputStream(bout);
+        dout.writeUTF(cfm.tableName);
+        dout.writeUTF(cfm.cfName);
+        dout.writeUTF(cfm.columnType);
+        dout.writeUTF(cfm.comparator.getClass().getName());
+        dout.writeBoolean(cfm.subcolumnComparator != null);
+        if (cfm.subcolumnComparator != null)
+            dout.writeUTF(cfm.subcolumnComparator.getClass().getName());
+        dout.writeBoolean(cfm.comment != null);
+        if (cfm.comment != null)
+            dout.writeUTF(cfm.comment);
+        dout.writeDouble(cfm.rowCacheSize);
+        dout.writeDouble(cfm.keysCachedFraction);
+        dout.close();
+        return bout.toByteArray();
+    }
+
+    public static CFMetaData deserialize(InputStream in) throws IOException
+    {
+
+        DataInputStream din = new DataInputStream(in);
+        String tableName = din.readUTF();
+        String cfName = din.readUTF();
+        String columnType = din.readUTF();
+        AbstractType comparator = null;
+        try
+        {
+            comparator = 
(AbstractType)Class.forName(din.readUTF()).newInstance();
+        }
+        catch (Exception ex)
+        {
+            throw new IOException(ex);
+        }
+        AbstractType subcolumnComparator = null;
+        try
+        {
+            subcolumnComparator = din.readBoolean() ? 
(AbstractType)Class.forName(din.readUTF()).newInstance() : null;
+        }
+        catch (Exception ex)
+        {
+
+        }
+        String comment = din.readBoolean() ? din.readUTF() : null;
+        double rowCacheSize = din.readDouble();
+        double keysCachedFraction = din.readDouble();
+        return new CFMetaData(tableName, cfName, columnType, comparator, 
subcolumnComparator, comment, rowCacheSize, keysCachedFraction);
+    }
+
+    public boolean equals(Object obj)
+    {
+        if (!(obj instanceof CFMetaData))
+            return false;
+        CFMetaData other = (CFMetaData)obj;
+        return other.tableName.equals(tableName)
+                && other.cfName.equals(cfName)
+                && other.columnType.equals(columnType)
+                && other.comparator.equals(comparator)
+                && FBUtilities.equals(other.subcolumnComparator, 
subcolumnComparator)
+                && FBUtilities.equals(other.comment, comment)
+                && other.rowCacheSize == rowCacheSize
+                && other.keysCachedFraction == keysCachedFraction;
+    }
 }

Modified: 
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
URL: 
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java?rev=915533&r1=915532&r2=915533&view=diff
==============================================================================
--- 
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
 (original)
+++ 
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
 Tue Feb 23 21:48:31 2010
@@ -26,16 +26,19 @@
 import org.apache.cassandra.db.marshal.BytesType;
 import org.apache.cassandra.db.marshal.UTF8Type;
 import org.apache.cassandra.dht.IPartitioner;
+import org.apache.cassandra.locator.EndPointSnitch;
 import org.apache.cassandra.locator.IEndPointSnitch;
 import org.apache.cassandra.locator.AbstractReplicationStrategy;
 import org.apache.cassandra.io.util.FileUtils;
-import org.apache.cassandra.utils.Pair;
 import org.apache.cassandra.utils.XMLUtils;
 import org.apache.log4j.Logger;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
 
+import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathExpressionException;
 import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
@@ -84,29 +87,13 @@
     private static double flushDataBufferSizeInMB_ = 32;
     private static double flushIndexBufferSizeInMB_ = 8;
     private static int slicedReadBufferSizeInKB_ = 64;
-    private static Set<String> tables_ = new HashSet<String>();
-    private static int bmtThreshold_ = 256;
-
-    private static Map<Pair<String, String>, Double> tableKeysCachedFractions_ 
= new HashMap<Pair<String, String>, Double>();
-    private static Map<Pair<String, String>, Double> tableRowCacheSizes = new 
HashMap<Pair<String, String>, Double>();
 
-    /*
-     * A map from table names to the set of column families for the table and 
the
-     * corresponding meta data for that column family.
-    */
-    private static Map<String, Map<String, CFMetaData>> tableToCFMetaDataMap_;
-
-    // map tables to replication strategies.
-    private static Map<String, Class<AbstractReplicationStrategy>> 
replicationStrategyClasses_;
-
-    // map tables to replication factors.
-    private static Map<String, Integer> replicationFactors_;
+    static Map<String, KSMetaData> tables_ = new HashMap<String, KSMetaData>();
+    private static int bmtThreshold_ = 256;
 
     /* Hashing strategy Random or OPHF */
     private static IPartitioner partitioner_;
 
-    private static Map<String, IEndPointSnitch> endPointSnitches_;
-
     /* if the size of columns or super-columns are more than this, indexing 
will kick in */
     private static int columnIndexSizeInKB_;
     /* Number of minutes to keep a memtable in memory */
@@ -457,41 +444,111 @@
             if ( value != null)
                 CommitLog.setSegmentSize(Integer.parseInt(value) * 1024 * 
1024);
 
-            tableToCFMetaDataMap_ = new HashMap<String, Map<String, 
CFMetaData>>();
-            replicationFactors_ = new HashMap<String, Integer>();
-            replicationStrategyClasses_ = new HashMap<String, 
Class<AbstractReplicationStrategy>>();
-            endPointSnitches_ = new HashMap<String, IEndPointSnitch>();
+            readTablesFromXml();
+            if (tables_.isEmpty())
+                throw new ConfigurationException("No keyspaces configured");
 
-            /* Read the table related stuff from config */
+            // Hardcoded system tables
+            KSMetaData systemMeta = new KSMetaData(Table.SYSTEM_TABLE, null, 
-1, null);
+            tables_.put(Table.SYSTEM_TABLE, systemMeta);
+            systemMeta.cfMetaData.put(SystemTable.STATUS_CF, new 
CFMetaData(Table.SYSTEM_TABLE,
+                                                                            
SystemTable.STATUS_CF,
+                                                                            
"Standard",
+                                                                            
new UTF8Type(),
+                                                                            
null,
+                                                                            
"persistent metadata for the local node",
+                                                                            0d,
+                                                                            
0.01d));
+
+            systemMeta.cfMetaData.put(HintedHandOffManager.HINTS_CF, new 
CFMetaData(Table.SYSTEM_TABLE,
+                                                                               
     HintedHandOffManager.HINTS_CF,
+                                                                               
     "Super",
+                                                                               
     new UTF8Type(),
+                                                                               
     new BytesType(),
+                                                                               
     "hinted handoff data",
+                                                                               
     0d,
+                                                                               
     0.01d));
+
+            /* Load the seeds for node contact points */
+            String[] seeds = xmlUtils.getNodeValues("/Storage/Seeds/Seed");
+            if (seeds.length <= 0)
+            {
+                throw new ConfigurationException("A minimum of one seed is 
required.");
+            }
+            for( int i = 0; i < seeds.length; ++i )
+            {
+                seeds_.add(InetAddress.getByName(seeds[i]));
+            }
+        }
+        catch (ConfigurationException e)
+        {
+            logger_.error("Fatal error: " + e.getMessage());
+            System.err.println("Bad configuration; unable to start server");
+            System.exit(1);
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static void readTablesFromXml() throws ConfigurationException
+    {
+        XMLUtils xmlUtils = null;
+        try
+        {
+            xmlUtils = new XMLUtils(configFileName_);
+        }
+        catch (ParserConfigurationException e)
+        {
+            ConfigurationException ex = new 
ConfigurationException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        }
+        catch (SAXException e)
+        {
+            ConfigurationException ex = new 
ConfigurationException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        }
+        catch (IOException e)
+        {
+            ConfigurationException ex = new 
ConfigurationException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        }
+
+        /* Read the table related stuff from config */
+        try
+        {
             NodeList tables = 
xmlUtils.getRequestedNodeList("/Storage/Keyspaces/Keyspace");
             int size = tables.getLength();
             for ( int i = 0; i < size; ++i )
             {
+                String value = null;
                 Node table = tables.item(i);
 
-                /* parsing out the table name */
-                String tName = XMLUtils.getAttributeValue(table, "Name");
-                if (tName == null)
+                /* parsing out the table ksName */
+                String ksName = XMLUtils.getAttributeValue(table, "Name");
+                if (ksName == null)
                 {
                     throw new ConfigurationException("Table name attribute is 
required");
                 }
-                if (tName.equalsIgnoreCase(Table.SYSTEM_TABLE))
+                if (ksName.equalsIgnoreCase(Table.SYSTEM_TABLE))
                 {
                     throw new ConfigurationException("'system' is a reserved 
table name for Cassandra internals");
                 }
-                tables_.add(tName);
-                tableToCFMetaDataMap_.put(tName, new HashMap<String, 
CFMetaData>());
 
                 /* See which replica placement strategy to use */
-                String replicaPlacementStrategyClassName = 
xmlUtils.getNodeValue("/Storage/Keyspaces/keyspa...@name='" + tName + 
"']/ReplicaPlacementStrategy");
+                String replicaPlacementStrategyClassName = 
xmlUtils.getNodeValue("/Storage/Keyspaces/keyspa...@name='" + ksName + 
"']/ReplicaPlacementStrategy");
                 if (replicaPlacementStrategyClassName == null)
                 {
-                    throw new ConfigurationException("Missing 
replicaplacementstrategy directive for " + tName);
+                    throw new ConfigurationException("Missing 
replicaplacementstrategy directive for " + ksName);
                 }
+                Class<? extends AbstractReplicationStrategy> repStratClass = 
null;
                 try
                 {
-                    Class cls = (Class<AbstractReplicationStrategy>) 
Class.forName(replicaPlacementStrategyClassName);
-                    replicationStrategyClasses_.put(tName, cls);
+                    repStratClass = (Class<? extends 
AbstractReplicationStrategy>) Class.forName(replicaPlacementStrategyClassName);
                 }
                 catch (ClassNotFoundException e)
                 {
@@ -499,37 +556,60 @@
                 }
 
                 /* Data replication factor */
-                String replicationFactor = 
xmlUtils.getNodeValue("/Storage/Keyspaces/keyspa...@name='" + tName + 
"']/ReplicationFactor");
+                String replicationFactor = 
xmlUtils.getNodeValue("/Storage/Keyspaces/keyspa...@name='" + ksName + 
"']/ReplicationFactor");
+                int repFact = -1;
                 if (replicationFactor == null)
-                    throw new ConfigurationException("Missing 
replicationfactor directory for keyspace " + tName);
+                    throw new ConfigurationException("Missing 
replicationfactor directory for keyspace " + ksName);
                 else
-                    replicationFactors_.put(tName, 
Integer.parseInt(replicationFactor));
+                {
+                    repFact = Integer.parseInt(replicationFactor);
+                }
 
                 /* end point snitch */
-                String endPointSnitchClassName = 
xmlUtils.getNodeValue("/Storage/Keyspaces/keyspa...@name='" + tName + 
"']/EndPointSnitch");
+                String endPointSnitchClassName = 
xmlUtils.getNodeValue("/Storage/Keyspaces/keyspa...@name='" + ksName + 
"']/EndPointSnitch");
                 if (endPointSnitchClassName == null)
                 {
-                    throw new ConfigurationException("Missing endpointsnitch 
directive for keyspace " + tName);
+                    throw new ConfigurationException("Missing endpointsnitch 
directive for keyspace " + ksName);
                 }
+                IEndPointSnitch epSnitch = null;
                 try
                 {
                     Class cls = Class.forName(endPointSnitchClassName);
-                    endPointSnitches_.put(tName, 
(IEndPointSnitch)cls.getConstructor().newInstance());
+                    epSnitch = 
(IEndPointSnitch)cls.getConstructor().newInstance();
                 }
                 catch (ClassNotFoundException e)
                 {
                     throw new ConfigurationException("Invalid endpointsnitch 
class " + endPointSnitchClassName);
                 }
+                catch (NoSuchMethodException e)
+                {
+                    throw new ConfigurationException("Invalid endpointsnitch 
class " + endPointSnitchClassName + " " + e.getMessage());
+                }
+                catch (InstantiationException e)
+                {
+                    throw new ConfigurationException("Invalid endpointsnitch 
class " + endPointSnitchClassName + " " + e.getMessage());
+                }
+                catch (IllegalAccessException e)
+                {
+                    throw new ConfigurationException("Invalid endpointsnitch 
class " + endPointSnitchClassName + " " + e.getMessage());
+                }
+                catch (InvocationTargetException e)
+                {
+                    throw new ConfigurationException("Invalid endpointsnitch 
class " + endPointSnitchClassName + " " + e.getMessage());
+                }
 
-                String xqlTable = "/Storage/Keyspaces/keyspa...@name='" + 
tName + "']/";
+                String xqlTable = "/Storage/Keyspaces/keyspa...@name='" + 
ksName + "']/";
                 NodeList columnFamilies = 
xmlUtils.getRequestedNodeList(xqlTable + "ColumnFamily");
 
+                KSMetaData meta = new KSMetaData(ksName, repStratClass, 
repFact, epSnitch);
+
                 //NodeList columnFamilies = 
xmlUtils.getRequestedNodeList(table, "ColumnFamily");
                 int size2 = columnFamilies.getLength();
 
                 for ( int j = 0; j < size2; ++j )
                 {
                     Node columnFamily = columnFamilies.item(j);
+                    String tableName = ksName;
                     String cfName = XMLUtils.getAttributeValue(columnFamily, 
"Name");
                     if (cfName == null)
                     {
@@ -551,7 +631,7 @@
                     }
 
                     // Parse out the column comparator
-                    AbstractType columnComparator = 
getComparator(columnFamily, "CompareWith");
+                    AbstractType comparator = getComparator(columnFamily, 
"CompareWith");
                     AbstractType subcolumnComparator = null;
                     if (columnType.equals("Super"))
                     {
@@ -562,86 +642,47 @@
                         throw new 
ConfigurationException("CompareSubcolumnsWith is only a valid attribute on 
super columnfamilies (not regular columnfamily " + cfName + ")");
                     }
 
+                    double keysCachedFraction = 0.01d;
                     if ((value = XMLUtils.getAttributeValue(columnFamily, 
"KeysCachedFraction")) != null)
                     {
-                        tableKeysCachedFractions_.put(Pair.create(tName, 
cfName), Double.valueOf(value));
+                        keysCachedFraction = Double.valueOf(value);
                     }
-                    
+
+                    double rowCacheSize = 0;
                     if ((value = XMLUtils.getAttributeValue(columnFamily, 
"RowsCached")) != null)
                     {
                         if (value.endsWith("%"))
                         {
-                            tableRowCacheSizes.put(Pair.create(tName, cfName), 
Double.valueOf(value.substring(0, value.length() - 1)) / 100);
+                            rowCacheSize = Double.valueOf(value.substring(0, 
value.length() - 1)) / 100;
                         }
                         else
                         {
-                            tableRowCacheSizes.put(Pair.create(tName, cfName), 
Double.valueOf(value));
+                            rowCacheSize = Double.valueOf(value);
                         }
                     }
 
                     // Parse out user-specified logical names for the various 
dimensions
                     // of a the column family from the config.
-                    String cfComment = xmlUtils.getNodeValue(xqlCF + 
"Comment");
+                    String comment = xmlUtils.getNodeValue(xqlCF + "Comment");
 
-                    // now populate the column family meta data and
                     // insert it into the table dictionary.
-                    CFMetaData cfMetaData = new CFMetaData();
-
-                    cfMetaData.tableName = tName;
-                    cfMetaData.cfName = cfName;
-                    cfMetaData.comment = cfComment;
-
-                    cfMetaData.columnType = columnType;
-                    cfMetaData.comparator = columnComparator;
-                    cfMetaData.subcolumnComparator = subcolumnComparator;
-
-                    tableToCFMetaDataMap_.get(tName).put(cfName, cfMetaData);
+                    meta.cfMetaData.put(cfName, new CFMetaData(tableName, 
cfName, columnType, comparator, subcolumnComparator, comment, rowCacheSize, 
keysCachedFraction));
                 }
-            }
-            if (tables_.isEmpty())
-                throw new ConfigurationException("No keyspaces configured");
-
-            // Hardcoded system tables
-            tables_.add(Table.SYSTEM_TABLE);
-            Map<String, CFMetaData> systemMetadata = new HashMap<String, 
CFMetaData>();
-
-            CFMetaData data = new CFMetaData();
-            data.cfName = SystemTable.STATUS_CF;
-            data.columnType = "Standard";
-            data.comparator = new UTF8Type();
-            data.comment = "persistent metadata for the local node";
-            systemMetadata.put(data.cfName, data);
-
-            data = new CFMetaData();
-            data.cfName = HintedHandOffManager.HINTS_CF;
-            data.columnType = "Super";
-            data.comparator = new UTF8Type();
-            data.subcolumnComparator = new BytesType();
-            data.comment = "hinted handoff data";
-            systemMetadata.put(data.cfName, data);
 
-            tableToCFMetaDataMap_.put(Table.SYSTEM_TABLE, systemMetadata);
-
-            /* Load the seeds for node contact points */
-            String[] seeds = xmlUtils.getNodeValues("/Storage/Seeds/Seed");
-            if (seeds.length <= 0)
-            {
-                throw new ConfigurationException("A minimum of one seed is 
required.");
-            }
-            for( int i = 0; i < seeds.length; ++i )
-            {
-                seeds_.add(InetAddress.getByName(seeds[i]));
+                tables_.put(meta.name, meta);
             }
         }
-        catch (ConfigurationException e)
+        catch (XPathExpressionException e)
         {
-            logger_.error("Fatal error: " + e.getMessage());
-            System.err.println("Bad configuration; unable to start server");
-            System.exit(1);
+            ConfigurationException ex = new 
ConfigurationException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
         }
-        catch (Exception e)
+        catch (TransformerException e)
         {
-            throw new RuntimeException(e);
+            ConfigurationException ex = new 
ConfigurationException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
         }
     }
 
@@ -655,11 +696,21 @@
         return thriftFramed_;
     }
 
-    private static AbstractType getComparator(Node columnFamily, String attr)
-    throws ConfigurationException, TransformerException, 
NoSuchMethodException, InvocationTargetException, IllegalAccessException, 
InstantiationException
+    private static AbstractType getComparator(Node columnFamily, String attr) 
throws ConfigurationException
+//    throws ConfigurationException, TransformerException, 
NoSuchMethodException, InvocationTargetException, IllegalAccessException, 
InstantiationException
     {
         Class<? extends AbstractType> typeClass;
-        String compareWith = XMLUtils.getAttributeValue(columnFamily, attr);
+        String compareWith = null;
+        try
+        {
+            compareWith = XMLUtils.getAttributeValue(columnFamily, attr);
+        }
+        catch (TransformerException e)
+        {
+            ConfigurationException ex = new 
ConfigurationException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        }
         if (compareWith == null)
         {
             typeClass = BytesType.class;
@@ -676,7 +727,34 @@
                 throw new ConfigurationException("Unable to load class " + 
className + " for " + attr + " attribute");
             }
         }
-        return typeClass.getConstructor().newInstance();
+        try
+        {
+            return typeClass.getConstructor().newInstance();
+        }
+        catch (InstantiationException e)
+        {
+            ConfigurationException ex = new 
ConfigurationException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        }
+        catch (IllegalAccessException e)
+        {
+            ConfigurationException ex = new 
ConfigurationException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        }
+        catch (InvocationTargetException e)
+        {
+            ConfigurationException ex = new 
ConfigurationException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        }
+        catch (NoSuchMethodException e)
+        {
+            ConfigurationException ex = new 
ConfigurationException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        }
     }
 
     /**
@@ -707,7 +785,7 @@
         for (String dataFile : dataFileDirectories_)
         {
             FileUtils.createDirectory(dataFile + File.separator + 
Table.SYSTEM_TABLE);
-            for (String table : tables_)
+            for (String table : tables_.keySet())
             {
                 String oneDir = dataFile + File.separator + table;
                 FileUtils.createDirectory(oneDir);
@@ -729,7 +807,7 @@
     public static void storeMetadata() throws IOException
     {
         int cfId = 0;
-        Set<String> tables = tableToCFMetaDataMap_.keySet();
+        Set<String> tables = tables_.keySet();
 
         for (String table : tables)
         {
@@ -738,7 +816,7 @@
             {
                 tmetadata = Table.TableMetadata.instance(table);
                 /* Column families associated with this table */
-                Map<String, CFMetaData> columnFamilies = 
tableToCFMetaDataMap_.get(table);
+                Map<String, CFMetaData> columnFamilies = 
tables_.get(table).cfMetaData;
 
                 for (String columnFamily : columnFamilies.keySet())
                 {
@@ -760,12 +838,12 @@
     
     public static IEndPointSnitch getEndPointSnitch(String table)
     {
-        return endPointSnitches_.get(table);
+        return tables_.get(table).epSnitch;
     }
 
-    public static Class<AbstractReplicationStrategy> 
getReplicaPlacementStrategyClass(String table)
+    public static Class<? extends AbstractReplicationStrategy> 
getReplicaPlacementStrategyClass(String table)
     {
-        return replicationStrategyClasses_.get(table);
+        return tables_.get(table).repStratClass;
     }
     
     public static String getJobTrackerAddress()
@@ -820,7 +898,9 @@
     public static Map<String, CFMetaData> getTableMetaData(String tableName)
     {
         assert tableName != null;
-        return tableToCFMetaDataMap_.get(tableName);
+        KSMetaData ksm = tables_.get(tableName);
+        assert ksm != null;
+        return Collections.unmodifiableMap(ksm.cfMetaData);
     }
 
     /*
@@ -831,11 +911,10 @@
     public static CFMetaData getCFMetaData(String tableName, String cfName)
     {
         assert tableName != null;
-        Map<String, CFMetaData> cfInfo = tableToCFMetaDataMap_.get(tableName);
-        if (cfInfo == null)
+        KSMetaData ksm = tables_.get(tableName);
+        if (ksm == null)
             return null;
-        
-        return cfInfo.get(cfName);
+        return ksm.cfMetaData.get(cfName);
     }
     
     public static String getColumnType(String tableName, String cfName)
@@ -850,12 +929,12 @@
 
     public static Set<String> getTables()
     {
-        return tables_;
+        return tables_.keySet();
     }
 
     public static List<String> getNonSystemTables()
     {
-        List<String> tables = new ArrayList<String>(tables_);
+        List<String> tables = new ArrayList<String>(tables_.keySet());
         tables.remove(Table.SYSTEM_TABLE);
         return Collections.unmodifiableList(tables);
     }
@@ -877,12 +956,12 @@
 
     public static int getReplicationFactor(String table)
     {
-        return replicationFactors_.get(table);
+        return tables_.get(table).replicationFactor;
     }
 
     public static int getQuorum(String table)
     {
-        return (replicationFactors_.get(table) / 2) + 1;
+        return (tables_.get(table).replicationFactor / 2) + 1;
     }
 
     public static long getRpcTimeout()
@@ -1006,21 +1085,20 @@
         return getCFMetaData(tableName, cfName).subcolumnComparator;
     }
 
-    public static Map<String, Map<String, CFMetaData>> 
getTableToColumnFamilyMap()
-    {
-        return tableToCFMetaDataMap_;
-    }
-
     public static double getKeysCachedFraction(String tableName, String 
columnFamilyName)
     {
-        Double v = tableKeysCachedFractions_.get(Pair.create(tableName, 
columnFamilyName));
-        return v == null ? 0.01 : v;
+        CFMetaData cfm = getCFMetaData(tableName, columnFamilyName);
+        if (cfm == null)
+            return 0.01d;
+        return cfm.keysCachedFraction;
     }
 
     public static double getRowsCachedFraction(String tableName, String 
columnFamilyName)
     {
-        Double v = tableRowCacheSizes.get(Pair.create(tableName, 
columnFamilyName));
-        return v == null ? 0 : v;
+        CFMetaData cfm = getCFMetaData(tableName, columnFamilyName);
+        if (cfm == null)
+            return 0.01d;
+        return cfm.rowCacheSize;
     }
 
     private static class ConfigurationException extends Exception
@@ -1099,13 +1177,4 @@
     {
         return autoBootstrap_;
     }
-
-    /**
-     * For testing purposes.
-     */
-    static void setReplicationFactorUnsafe(String table, int factor)
-    {
-        replicationFactors_.remove(table);
-        replicationFactors_.put(table, factor);
-    }
 }

Added: 
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java
URL: 
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java?rev=915533&view=auto
==============================================================================
--- 
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java 
(added)
+++ 
incubator/cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java 
Tue Feb 23 21:48:31 2010
@@ -0,0 +1,136 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.config;
+
+import org.apache.cassandra.locator.AbstractReplicationStrategy;
+import org.apache.cassandra.locator.IEndPointSnitch;
+import org.apache.cassandra.utils.FBUtilities;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+public final class KSMetaData
+{
+    public final String name;
+    public final Class<? extends AbstractReplicationStrategy> repStratClass;
+    public final int replicationFactor;
+    public final IEndPointSnitch epSnitch;
+    public final Map<String, CFMetaData> cfMetaData = new HashMap<String, 
CFMetaData>();
+
+    KSMetaData(String name, Class<? extends AbstractReplicationStrategy> 
repStratClass, int replicationFactor, IEndPointSnitch epSnitch)
+    {
+        this.name = name;
+        this.repStratClass = repStratClass;
+        this.replicationFactor = replicationFactor;
+        this.epSnitch = epSnitch;
+    }
+    
+    public boolean equals(Object obj)
+    {
+        if (obj == null)
+            return false;
+        if (!(obj instanceof KSMetaData))
+            return false;
+        KSMetaData other = (KSMetaData)obj;
+        return other.name.equals(name)
+                && FBUtilities.equals(other.repStratClass, repStratClass)
+                && other.replicationFactor == replicationFactor
+                && sameEpSnitch(other, this)
+                && other.cfMetaData.size() == cfMetaData.size()
+                && other.cfMetaData.equals(cfMetaData);
+    }
+
+    // epsnitches generally have no state, so comparing class names is 
sufficient.
+    private static boolean sameEpSnitch(KSMetaData a, KSMetaData b)
+    {
+        if (a.epSnitch == null && b.epSnitch == null)
+            return true;
+        else if (a.epSnitch == null && b.epSnitch != null)
+            return false;
+        else if (a.epSnitch != null && b.epSnitch == null)
+            return false;
+        else
+            return 
a.epSnitch.getClass().getName().equals(b.epSnitch.getClass().getName());
+    }
+    
+    public static byte[] serialize(KSMetaData ksm) throws IOException
+    {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        DataOutputStream dout = new DataOutputStream(bout);
+        dout.writeUTF(ksm.name);
+        dout.writeBoolean(ksm.repStratClass != null);
+        if (ksm.repStratClass != null)
+            dout.writeUTF(ksm.repStratClass.getName());
+        dout.writeInt(ksm.replicationFactor);
+        dout.writeBoolean(ksm.epSnitch != null);
+        if (ksm.epSnitch != null)
+            dout.writeUTF(ksm.epSnitch.getClass().getName());
+        dout.writeInt(ksm.cfMetaData.size());
+        for (CFMetaData cfm : ksm.cfMetaData.values())
+            dout.write(CFMetaData.serialize(cfm));
+        dout.close();
+        return bout.toByteArray();
+    }
+
+    public static KSMetaData deserialize(InputStream in) throws IOException
+    {
+        DataInputStream din = new DataInputStream(in);
+        String name = din.readUTF();
+        Class<AbstractReplicationStrategy> repStratClass = null;
+        try
+        {
+            repStratClass = din.readBoolean() ? 
(Class<AbstractReplicationStrategy>)Class.forName(din.readUTF()) : null;
+        }
+        catch (Exception ex)
+        {
+            throw new IOException(ex);
+        }
+        int replicationFactor = din.readInt();
+        IEndPointSnitch epSnitch = null;
+        try
+        {
+            epSnitch = din.readBoolean() ? 
(IEndPointSnitch)Class.forName(din.readUTF()).newInstance() : null;
+        }
+        catch (Exception ex)
+        {
+            throw new IOException(ex);
+        }
+        int cfsz = din.readInt();
+        KSMetaData ksm = new KSMetaData(name, repStratClass, 
replicationFactor, epSnitch);
+        for (int i = 0; i < cfsz; i++)
+        {
+            try
+            {
+                CFMetaData cfm = CFMetaData.deserialize(din);
+                ksm.cfMetaData.put(cfm.cfName, cfm);
+            }
+            catch (IOException ex)
+            {
+                System.err.println(ksm.name);
+                throw ex;
+            }
+        }
+        return ksm;
+    }
+}

Modified: 
incubator/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java
URL: 
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java?rev=915533&r1=915532&r2=915533&view=diff
==============================================================================
--- 
incubator/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java
 (original)
+++ 
incubator/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java
 Tue Feb 23 21:48:31 2010
@@ -86,4 +86,12 @@
         }
         return builder.toString();
     }
+
+    public final boolean equals(Object obj)
+    {
+        if (obj == null)
+            return false;
+        else
+            return obj.getClass().getName().equals(getClass().getName());
+    }
 }

Modified: 
incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java
URL: 
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java?rev=915533&r1=915532&r2=915533&view=diff
==============================================================================
--- 
incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java
 (original)
+++ 
incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java
 Tue Feb 23 21:48:31 2010
@@ -250,13 +250,13 @@
     public static AbstractReplicationStrategy 
getReplicationStrategy(TokenMetadata tokenMetadata, String table)
     {
         AbstractReplicationStrategy replicationStrategy = null;
-        Class<AbstractReplicationStrategy> cls = 
DatabaseDescriptor.getReplicaPlacementStrategyClass(table);
+        Class<? extends AbstractReplicationStrategy> cls = 
DatabaseDescriptor.getReplicaPlacementStrategyClass(table);
         if (cls == null)
             throw new RuntimeException(String.format("No replica strategy 
configured for %s", table));
         Class [] parameterTypes = new Class[] { TokenMetadata.class, 
IEndPointSnitch.class};
         try
         {
-            Constructor<AbstractReplicationStrategy> constructor = 
cls.getConstructor(parameterTypes);
+            Constructor<? extends AbstractReplicationStrategy> constructor = 
cls.getConstructor(parameterTypes);
             replicationStrategy = constructor.newInstance(tokenMetadata, 
DatabaseDescriptor.getEndPointSnitch(table));
         }
         catch (Exception e)

Modified: 
incubator/cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java
URL: 
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java?rev=915533&r1=915532&r2=915533&view=diff
==============================================================================
--- 
incubator/cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java 
(original)
+++ 
incubator/cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java 
Tue Feb 23 21:48:31 2010
@@ -415,4 +415,16 @@
             Collections.sort(keys);
         }
     }
+
+    public static boolean equals(Object a, Object b)
+    {
+        if (a == null && b == null)
+            return true;
+        else if (a != null && b == null)
+            return false;
+        else if (a == null && b != null)
+            return false;
+        else
+            return a.equals(b);
+    }
 }

Modified: 
incubator/cassandra/trunk/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
URL: 
http://svn.apache.org/viewvc/incubator/cassandra/trunk/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java?rev=915533&r1=915532&r2=915533&view=diff
==============================================================================
--- 
incubator/cassandra/trunk/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
 (original)
+++ 
incubator/cassandra/trunk/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
 Tue Feb 23 21:48:31 2010
@@ -21,6 +21,9 @@
 import static org.junit.Assert.assertNotNull;
 import org.junit.Test;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
 public class DatabaseDescriptorTest
 {
     @Test
@@ -29,13 +32,32 @@
         assertNotNull(DatabaseDescriptor.getConfigFileName(), 
"DatabaseDescriptor should always be able to return the file name of the config 
file");
     }
 
-    /**
-     * Allow modification of replicationFactor for testing purposes.
-     * TODO: A more general method of property modification would be useful, 
but
-     *       will probably have to wait for a refactor away from all the 
static fields.
-     */
-    public static void setReplicationFactor(String table, int factor)
+    @Test
+    public void testCFMetaDataSerialization() throws IOException
+    {
+        // test serialization of all defined test CFs.
+        for (String table : DatabaseDescriptor.getNonSystemTables())
+        {
+            for (CFMetaData cfm : 
DatabaseDescriptor.getTableMetaData(table).values())
+            {
+                byte[] ser = CFMetaData.serialize(cfm);
+                CFMetaData cfmDupe = CFMetaData.deserialize(new 
ByteArrayInputStream(ser));
+                assert cfmDupe != null;
+                assert cfmDupe.equals(cfm);
+            }
+        }
+
+    }
+
+    @Test
+    public void testKSMetaDataSerialization() throws IOException 
     {
-        DatabaseDescriptor.setReplicationFactorUnsafe(table, factor);
+        for (KSMetaData ksm : DatabaseDescriptor.tables_.values())
+        {
+            byte[] ser = KSMetaData.serialize(ksm);
+            KSMetaData ksmDupe = KSMetaData.deserialize(new 
ByteArrayInputStream(ser));
+            assert ksmDupe != null;
+            assert ksmDupe.equals(ksm);
+        }
     }
 }

Modified: 
incubator/cassandra/trunk/test/unit/org/apache/cassandra/service/AntiEntropyServiceTest.java
URL: 
http://svn.apache.org/viewvc/incubator/cassandra/trunk/test/unit/org/apache/cassandra/service/AntiEntropyServiceTest.java?rev=915533&r1=915532&r2=915533&view=diff
==============================================================================
--- 
incubator/cassandra/trunk/test/unit/org/apache/cassandra/service/AntiEntropyServiceTest.java
 (original)
+++ 
incubator/cassandra/trunk/test/unit/org/apache/cassandra/service/AntiEntropyServiceTest.java
 Tue Feb 23 21:48:31 2010
@@ -61,9 +61,7 @@
         if (!initialized)
         {
             LOCAL = FBUtilities.getLocalAddress();
-            tablename = DatabaseDescriptor.getTables().iterator().next();
-            // bump the replication factor so that local overlaps with REMOTE 
below
-            DatabaseDescriptorTest.setReplicationFactor(tablename, 2);
+            tablename = "Keyspace4";
 
             StorageService.instance.initServer();
             // generate a fake endpoint for which we can spoof 
receiving/sending trees


Reply via email to