/*
* @(#)ShardedConfiguration.java 2012-8-1 下午10:00:00
*
* Copyright (c) 2011-2012 Makersoft.org all rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
*
*/
package org.makersoft.shards;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.session.SqlSessionFactory;
import org.makersoft.shards.cfg.ShardConfiguration;
import org.makersoft.shards.id.IdGenerator;
import org.makersoft.shards.session.ShardedSqlSessionFactory;
import org.makersoft.shards.session.impl.ShardedSqlSessionFactoryImpl;
import org.makersoft.shards.strategy.ShardStrategyFactory;
import org.makersoft.shards.utils.Assert;
import org.makersoft.shards.utils.Maps;
/**
* @author Feng Kuok
*/
public class ShardedConfiguration {
private final Log log = LogFactory.getLog(getClass());
// private final
// 分区配置
private final List<ShardConfiguration> shardConfigs;
// 用户自定义分区策略
private final ShardStrategyFactory shardStrategyFactory;
private final IdGenerator idGenerator;
// 虚拟分区ids --> 物理分区 ids 映射
private final Map<Integer, Integer> virtualShardToShardMap;
// 物理分区ids --> 虚拟分区ids集合 映射
private final Map<Integer, Set<ShardId>> shardToVirtualShardIdMap;
public ShardedConfiguration(List<ShardConfiguration> shardConfigs,
ShardStrategyFactory shardStrategyFactory, IdGenerator idGenerator) {
this(shardConfigs, shardStrategyFactory, new HashMap<Integer, Integer>(), idGenerator);
}
public ShardedConfiguration(List<ShardConfiguration> shardConfigs,
ShardStrategyFactory shardStrategyFactory,
Map<Integer, Integer> virtualShardToShardMap, IdGenerator idGenerator) {
Assert.notNull(shardConfigs);
Assert.notNull(shardStrategyFactory);
Assert.notNull(virtualShardToShardMap);
this.shardConfigs = shardConfigs;
this.shardStrategyFactory = shardStrategyFactory;
this.virtualShardToShardMap = virtualShardToShardMap;
this.idGenerator = idGenerator;
if (!virtualShardToShardMap.isEmpty()) {
// build the map from shard to set of virtual shards
shardToVirtualShardIdMap = Maps.newHashMap();
for (Map.Entry<Integer, Integer> entry : virtualShardToShardMap.entrySet()) {
Set<ShardId> set = shardToVirtualShardIdMap.get(entry.getValue());
// see if we already have a set of virtual shards
if (set == null) {
// we don't, so create it and add it to the map
set = new HashSet<ShardId>();
shardToVirtualShardIdMap.put(entry.getValue(), set);
}
set.add(new ShardId(entry.getKey()));
}
} else {
shardToVirtualShardIdMap = new HashMap<Integer, Set<ShardId>>();
}
}
public ShardedSqlSessionFactory buildShardedSessionFactory() {
Map<SqlSessionFactory, Set<ShardId>> sqlSessionFactories = new HashMap<SqlSessionFactory, Set<ShardId>>();
for (ShardConfiguration config : shardConfigs) {
// populatePrototypeWithVariableProperties(config);
// get the shardId from the shard-specific config
Integer shardId = config.getShardId();
if (shardId == null) {
final String msg = "Attempt to build a ShardedSessionFactory using a "
+ "ShardConfiguration that has a null shard id.";
log.fatal(msg);
throw new NullPointerException(msg);
}
Set<ShardId> virtualShardIds;
if (virtualShardToShardMap.isEmpty()) {
// simple case, virtual and physical are the same
virtualShardIds = Collections.singleton(new ShardId(shardId));
} else {
// get the set of shard ids that are mapped to the physical
// shard
// described by this config
virtualShardIds = shardToVirtualShardIdMap.get(shardId);
}
// sqlSessionFactories.put(buildSessionFactory(), virtualShardIds);
sqlSessionFactories.put(config.getSqlSessionFactory(), virtualShardIds);
}
// final boolean doFullCrossShardRelationshipChecking =
// PropertiesHelper.getBoolean(
// ShardedEnvironment.CHECK_ALL_ASSOCIATED_OBJECTS_FOR_DIFFERENT_SHARDS,
// prototypeConfiguration.getProperties(),
// true);
return new ShardedSqlSessionFactoryImpl(sqlSessionFactories, shardStrategyFactory,
idGenerator);
}
}