/*
* @(#)UserShardStrategyFactory.java 2012-9-12 下午12:57:18
*
* Copyright (c) 2011-2012 Makersoft.org all rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
*
*/
package org.makersoft.shards.strategy;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.ibatis.session.RowBounds;
import org.makersoft.shards.ShardId;
import org.makersoft.shards.domain.shard0.User;
import org.makersoft.shards.strategy.access.ShardAccessStrategy;
import org.makersoft.shards.strategy.access.impl.ParallelShardAccessStrategy;
import org.makersoft.shards.strategy.exit.impl.RowCountExitOperation;
import org.makersoft.shards.strategy.reduce.ShardReduceStrategy;
import org.makersoft.shards.strategy.resolution.ShardResolutionStrategy;
import org.makersoft.shards.strategy.resolution.ShardResolutionStrategyData;
import org.makersoft.shards.strategy.resolution.impl.AllShardsShardResolutionStrategy;
import org.makersoft.shards.strategy.selection.ShardSelectionStrategy;
/**
*
*/
public class UserShardStrategyFactory implements ShardStrategyFactory {
@Override
public ShardStrategy newShardStrategy(List<ShardId> shardIds) {
ShardSelectionStrategy pss = this.getShardSelectionStrategy(shardIds);
ShardResolutionStrategy prs = this.getShardResolutionStrategy(shardIds);
ShardAccessStrategy pas = this.getShardAccessStrategy();
ShardReduceStrategy srs = this.getShardReduceStrategy();
return new ShardStrategyImpl(pss, prs, pas, srs);
}
private ShardSelectionStrategy getShardSelectionStrategy(final List<ShardId> shardIds){
return new ShardSelectionStrategy(){
@Override
public ShardId selectShardIdForNewObject(String statement, Object obj) {
if(obj instanceof User){
User user = (User)obj;
return this.determineShardId(user.getGender());
}else {
return null;
}
}
private ShardId determineShardId(int gender) {
if(User.SEX_MALE == gender){
return ShardId.findByShardId(shardIds, 0);
}else if(User.SEX_FEMALE == gender){
return ShardId.findByShardId(shardIds, 1);
}
return null;
}
};
}
private ShardResolutionStrategy getShardResolutionStrategy(final List<ShardId> shardIds){
return new AllShardsShardResolutionStrategy(shardIds) {
@Override
public List<ShardId> selectShardIdsFromShardResolutionStrategyData(
ShardResolutionStrategyData shardResolutionStrategyData) {
String statement = shardResolutionStrategyData.getStatement();
Object parameter = shardResolutionStrategyData.getParameter();
// Serializable id = shardResolutionStrategyData.getId();
//自定义规则...
if(statement.endsWith("findByGender")){
if(((Integer)parameter) == User.SEX_MALE){
return Collections.singletonList(ShardId.findByShardId(shardIds, 0));
}else {
return Collections.singletonList(ShardId.findByShardId(shardIds, 1));
}
}
return super.getShardIds();
}
};
}
private ShardAccessStrategy getShardAccessStrategy() {
ThreadFactory factory = new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}
};
ThreadPoolExecutor exec = new ThreadPoolExecutor(10, 50, 60,
TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), factory);
return new ParallelShardAccessStrategy(exec);
// return new SequentialShardAccessStrategy();
}
private ShardReduceStrategy getShardReduceStrategy() {
return new ShardReduceStrategy() {
@Override
public List<Object> reduce(String statement, Object parameter, RowBounds rowBounds,
List<Object> values) {
if(statement.endsWith("getAllCount")){
return new RowCountExitOperation().apply(values);
}
return values;
}
};
}
}