/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB Inc.
*
* VoltDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VoltDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VoltDB. If not, see <http://www.gnu.org/licenses/>.
*/
package org.voltdb.sysprocs.saverestore;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.voltdb.VoltTable;
import org.voltdb.VoltTable.ColumnInfo;
import org.voltdb.VoltTableRow;
import org.voltdb.VoltType;
import org.voltdb.catalog.Host;
import org.voltdb.catalog.Site;
import org.voltdb.catalog.Table;
import edu.brown.hstore.PartitionExecutor.SystemProcedureExecutionContext;
public class ClusterSaveFileState
{
public static VoltTable constructEmptySaveFileStateVoltTable()
{
ColumnInfo[] result_columns = new ColumnInfo[10];
int ii = 0;
result_columns[ii++] = new ColumnInfo("CURRENT_HOST_ID", VoltType.INTEGER);
result_columns[ii++] = new ColumnInfo("CURRENT_HOSTNAME", VoltType.STRING);
result_columns[ii++] =
new ColumnInfo("ORIGINAL_HOST_ID", VoltType.INTEGER);
result_columns[ii++] =
new ColumnInfo("ORIGINAL_HOSTNAME", VoltType.STRING);
result_columns[ii++] = new ColumnInfo("CLUSTER", VoltType.STRING);
result_columns[ii++] = new ColumnInfo("DATABASE", VoltType.STRING);
result_columns[ii++] = new ColumnInfo("TABLE", VoltType.STRING);
result_columns[ii++] = new ColumnInfo("IS_REPLICATED", VoltType.STRING);
result_columns[ii++] = new ColumnInfo("PARTITION", VoltType.INTEGER);
result_columns[ii++] = new ColumnInfo("TOTAL_PARTITIONS",
VoltType.INTEGER);
return new VoltTable(result_columns);
}
private TableSaveFileState constructTableState(
VoltTableRow row)
{
TableSaveFileState table_state = null;
String table_name = row.getString("TABLE");
if (row.getString("IS_REPLICATED").equals("TRUE"))
{
table_state = new ReplicatedTableSaveFileState(table_name, m_allowExport);
table_state.setSystemProcedureExecutionContext(this.m_context);
}
else if (row.getString("IS_REPLICATED").equals("FALSE"))
{
table_state = new PartitionedTableSaveFileState(table_name, m_allowExport);
table_state.setSystemProcedureExecutionContext(this.m_context);
}
else
{
// XXX not reached
assert(false);
}
return table_state;
}
public ClusterSaveFileState(VoltTable saveFileState, SystemProcedureExecutionContext context, int allowExport)
throws IOException
{
if (saveFileState.getRowCount() == 0)
{
String error = "No savefile state to restore";
throw new IOException(error);
}
VoltTableRow a_row = saveFileState.fetchRow(0);
m_clusterName = a_row.getString("CLUSTER");
m_databaseName = a_row.getString("DATABASE");
m_allowExport = allowExport;
m_context = context;
m_tableStateMap = new HashMap<String, TableSaveFileState>();
while (saveFileState.advanceRow())
{
checkConsistency(saveFileState); // throws if inconsistent
String table_name = saveFileState.getString("TABLE");
TableSaveFileState table_state = null;
if (!(getSavedTableNames().contains(table_name)))
{
table_state = constructTableState(saveFileState);
m_tableStateMap.put(table_name, table_state);
}
table_state = getTableState(table_name);
table_state.addHostData(saveFileState); // throws if inconsistent
}
for (TableSaveFileState table_state : m_tableStateMap.values())
{
if (!table_state.isConsistent())
{
String error = "Table: " + table_state.getTableName() +
" has some inconsistency in the savefile state";
throw new IOException(error);
}
}
}
public Set<String> getSavedTableNames()
{
return m_tableStateMap.keySet();
}
public TableSaveFileState getTableState(String tableName)
{
return m_tableStateMap.get(tableName);
}
private void checkConsistency(VoltTableRow row) throws IOException
{
if (!row.getString("CLUSTER").equals(m_clusterName))
{
String error = "Site: " + row.getLong("CURRENT_HOST_ID") +
", Table: " + row.getString("TABLE") + " has an inconsistent " +
"cluster name: " + row.getString("CLUSTER") + " (previous was: " +
m_clusterName + ").";
throw new IOException(error);
}
if (!row.getString("DATABASE").equals(m_databaseName))
{
String error = "Site: " + row.getLong("CURRENT_HOST_ID") +
", Table: " + row.getString("TABLE") + " has an inconsistent " +
"database name: " + row.getString("DATABASE") + " (previous was: " +
m_databaseName + ").";
throw new IOException(error);
}
}
public void setSystemProcedureExecutionContext(SystemProcedureExecutionContext context){
m_context = context;
}
public SystemProcedureExecutionContext getSystemProcedureExecutionContext(){
return m_context;
}
private SystemProcedureExecutionContext m_context;
private String m_clusterName;
private String m_databaseName;
final private int m_allowExport;
private Map<String, TableSaveFileState> m_tableStateMap;
}