【Mycat1.6之加载Schema的DataNode源码解读】

一、Mycat1.6之加载Schema的DataNode源码解读


//<dataNode name="dn1" dataHost="localhost1_gaojingsong1" database="scott" />
private void load(String dtdFile, String xmlFile) {
	InputStream dtd = null;
	InputStream xml = null;
		 
	dtd = XMLSchemaLoader.class.getResourceAsStream(dtdFile);
	xml = XMLSchemaLoader.class.getResourceAsStream(xmlFile);
	Element root = ConfigUtil.getDocument(dtd, xml).getDocumentElement();
	//先加载所有的DataHost
	loadDataHosts(root);
	//再加载所有的DataNode
	loadDataNodes(root);
	//最后加载所有的Schema
	loadSchemas(root);
		 
}
//<dataNode name="dn1" dataHost="localhost1_gaojingsong1" database="scott" />
private void loadDataNodes(Element root) {
    //读取DataNode分支
    NodeList list = root.getElementsByTagName("dataNode");
	for (int i = 0, n = list.getLength(); i < n; i++) {
		Element element = (Element) list.item(i);
		String dnNamePre = element.getAttribute("name");

		String databaseStr = element.getAttribute("database");
		String host = element.getAttribute("dataHost");
		//字符串不为空
		if (empty(dnNamePre) || empty(databaseStr) || empty(host)) {
			throw new ConfigException("dataNode " + dnNamePre + " define error 
,attribute can't be empty");
		}
		//dnNames(name),databases(database),hostStrings(dataHost)都可以配置多
个,以',', '$', '-'区分,
		//但是需要保证database的个数*dataHost的个数=name的个数
		//多个dataHost与多个database如果写在一个标签,则每个dataHost拥有所有database
		//例如:
		//则为:localhost1拥有dn1$0-75,localhost2也拥有dn1$0-75(对应db$76-151)
	String[] dnNames = io.mycat.util.SplitUtil.split(dnNamePre, ',', '$', '-');
	String[] databases = io.mycat.util.SplitUtil.split(databaseStr, ',', '$', '-');
	String[] hostStrings = io.mycat.util.SplitUtil.split(host, ',', '$', '-');
        //此处复杂的配置关系请看步骤二实验结果,进行理解
		if (dnNames.length > 1 && dnNames.length != databases.length * hostStrings.length) {
			throw new ConfigException("dataNode " + dnNamePre
							+ " define error ,dnNames.length must be=databases.length*hostStrings.length");
		}
		if (dnNames.length > 1) {
			
			List<String[]> mhdList = mergerHostDatabase(hostStrings, databases);
			for (int k = 0; k < dnNames.length; k++) {
				String[] hd = mhdList.get(k);
				String dnName = dnNames[k];
				String databaseName = hd[1];
				String hostName = hd[0];
				createDataNode(dnName, databaseName, hostName);
			}

		} else {
			createDataNode(dnNamePre, databaseStr, host);
		}

	}
}

/**
	 * 匹配DataHost和Database,每个DataHost拥有每个Database名字
	 * @param hostStrings
	 * @param databases
     * @return
     */
private List<String[]> mergerHostDatabase(String[] hostStrings,	String[] databases) {
	List<String[]> mhdList = new ArrayList<>();
	for (int i = 0; i < hostStrings.length; i++) {
		String hostString = hostStrings[i];
		for (int i1 = 0; i1 < databases.length; i1++) {
			String database = databases[i1];
			String[] hd = new String[2];
			hd[0] = hostString;
			hd[1] = database;
			mhdList.add(hd);
		}
	}
	return mhdList;
}

private void createDataNode(String dnName, String database, String host) {
	DataNodeConfig conf = new DataNodeConfig(dnName, database, host);		
	if (dataNodes.containsKey(conf.getName())) {
		throw new ConfigException("dataNode " + conf.getName() + " duplicated!");
	}
	
	if (!dataHosts.containsKey(host)) {
		throw new ConfigException("dataNode " + dnName + " reference dataHost:" + host + " not exists!");
	}

	dataHosts.get(host).addDataNode(conf.getName());
	dataNodes.put(conf.getName(), conf);
}

public final class DataNodeConfig {
	private final String name;
	private final String database;
	private final String dataHost;
}

二、实验结果验证



 



 结论:

<dataNode name="dn1$0-75" dataHost="localhost$1-10" database="db$0-759" />

         name.length must be=databases.length*dataHost.length"

//从A到C地没有直达路径,需要经过B中转,已知从A到B有三条databases路,从B到C有2条dataHost路

//,试问从A到C有几种方案

猜你喜欢

转载自gaojingsong.iteye.com/blog/2374561