package com.tesora.dve.distribution;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import java.util.HashSet;
import java.util.Set;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import com.tesora.dve.common.catalog.CatalogDAO;
import com.tesora.dve.common.catalog.DistributionModel;
import com.tesora.dve.common.catalog.PersistentGroup;
import com.tesora.dve.common.catalog.PersistentSite;
import com.tesora.dve.common.catalog.StorageGroup;
import com.tesora.dve.common.catalog.StorageGroupGeneration;
import com.tesora.dve.common.catalog.UserTable;
import com.tesora.dve.db.DBEmptyTextResultConsumer;
import com.tesora.dve.db.DBResultConsumer.RowCountAdjuster;
import com.tesora.dve.exceptions.PEException;
import com.tesora.dve.queryplan.ExecutionState;
import com.tesora.dve.queryplan.QueryStepMultiTupleRedistOperation;
import com.tesora.dve.server.messaging.SQLCommand;
import com.tesora.dve.sql.schema.SchemaContext.DistKeyOpType;
import com.tesora.dve.worker.WorkerGroup;
import com.tesora.dve.worker.WorkerGroup.MappingSolution;
@Entity
@DiscriminatorValue(BroadcastDistributionModel.MODEL_NAME)
public class BroadcastDistributionModel extends DistributionModel {
private static final long serialVersionUID = 1L;
public final static String MODEL_NAME = "Broadcast";
public final static BroadcastDistributionModel SINGLETON = new BroadcastDistributionModel();
public BroadcastDistributionModel() {
super(MODEL_NAME);
}
@Override
public MappingSolution mapKeyForInsert(CatalogDAO c, StorageGroup wg,
IKeyValue key) throws PEException {
return MappingSolution.AllWorkersSerialized;
}
@Override
public MappingSolution mapKeyForUpdate(CatalogDAO c, StorageGroup wg,
IKeyValue key) throws PEException {
return MappingSolution.AllWorkersSerialized;
}
@Override
public MappingSolution mapKeyForQuery(CatalogDAO c, StorageGroup sg, IKeyValue key, DistKeyOpType operation)
throws PEException {
MappingSolution mappingSolution;
if (operation.equals(DistKeyOpType.SELECT_FOR_UPDATE))
mappingSolution = MappingSolution.AnyWorkerSerialized;
else
mappingSolution = MappingSolution.AnyWorker;
return mappingSolution;
}
@Override
public MappingSolution mapForQuery(WorkerGroup wg, SQLCommand command) throws PEException {
MappingSolution mappingSolution;
if (command.isForUpdateStatement())
mappingSolution = MappingSolution.AnyWorkerSerialized;
else
mappingSolution = MappingSolution.AnyWorker.lockMapping(wg);
return mappingSolution;
}
@Override
public void prepareGenerationAddition(ExecutionState estate, WorkerGroup wg, UserTable userTable, StorageGroupGeneration newGen) throws PEException {
Set<PersistentSite> netNewSites = new HashSet<PersistentSite>(newGen.getStorageSites());
netNewSites.removeAll(wg.getStorageSites());
PersistentGroup netNewSG = new PersistentGroup(netNewSites);
// if the new generation contains no net new sites, we don't need to create/populate the table
if ( netNewSG.sizeForProvisioning() != 0 ) {
// Create a new userTable from the old where the persistent group is just the new generation
UserTable redistTable = userTable.shallowClone();
redistTable.setPersistentGroup(netNewSG);
QueryStepMultiTupleRedistOperation qso =
new QueryStepMultiTupleRedistOperation(netNewSG, userTable.getDatabase(),
new SQLCommand(estate.getConnection(), "select * from " + userTable.getNameAsIdentifier()),
BroadcastDistributionModel.SINGLETON
).toUserTable(netNewSG, redistTable);
qso.executeSelf(estate, wg, DBEmptyTextResultConsumer.INSTANCE);
}
}
@Override
public void onUpdate() {
}
@Override
public void onDrop() {
}
@Override
public RowCountAdjuster getInsertAdjuster() {
return new RowCountAdjuster() {
@Override
public long adjust(long rawRowCount, int siteCount) {
return rawRowCount / siteCount;
}
};
}
@Override
public RowCountAdjuster getUpdateAdjuster() {
return getInsertAdjuster();
}
}