/*
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2005 satoshi akabane(akabane@logical-paradox.org)
 * $Id: Domain.java,v 1.2 2005/09/28 16:14:44 rampil Exp $
 */
package org.logical_paradox.vsan.domain;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.logical_paradox.vsan.node.DiskArrayNode;

/**
 * ドメイン情報
 * ドメインに接続したり切断したりします
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.2 $
 */
public class Domain implements Serializable {
	/** ドメイン名 */
	private final String name;
	/** ドメインに参加しているURIのリスト */
	private final HashMap uris = new HashMap();
	/** 自動領域拡張が可能なドメインかどうか */
	private boolean autoExpandable = true;
	/** レコードサイズ */
	private int recordSize = -1;

	/**
	 * コンストラクタ
	 * @param String dn ドメイン名
	 * @param nodes ドメインに参加しているノードのリスト
	 */
	public Domain(String dn, DiskArrayNode[] nodes) {
		name = dn;
		autoExpandable = true;

		// ノードのリストを追加する
		for(int i = 0; i < nodes.length; i++) {
			add(nodes[i]);
		}
	}
	/**
	 * コンストラクタ
	 * @param String dn ドメイン名
	 * @param nodes ドメインに参加しているノードのリスト
	 * @param ae 自動領域拡張可能かどうか(true:拡張可能 / false:拡張不可能)
	 */
	public Domain(String dn, DiskArrayNode[] nodes, boolean ae) {
		this(dn, nodes);
		autoExpandable = ae;
	}
	/**
	 * ドメインにノードが格納されているかどうかを返す．
	 * @return true:参加しているノードがある / false:参加しているノードがない
	 */
	public boolean isEmpty() {
		return uris.size() == 0;
	}
	/**
	 * ドメイン名を返す
	 * @return ドメイン名
	 */
	public String getDomainName() {
		return name;
	}
	/**
	 * このドメインに対してノードを追加する
	 * @param node ノード
	 */
	public void add(DiskArrayNode node) {
		if(recordSize < 0) {
			recordSize = node.getRecordSize();
		}
		uris.put(node.getHost(), node);
	}
	/**
	 * このドメインから指定ノードを離脱させる
	 * @param node 離脱対象ノード
	 */
	public void remove(String node) {
		uris.remove(node);
	}
	/**
	 * レコードサイズを返す．
	 * @return レコードサイズ
	 */
	public int getRecordSize() {
		return recordSize;
	}
	/**
	 * このドメインに参加しているノードを返す
	 * 返却されたノードのリストは更新不能とする
	 * @return ノード
	 */
	public Map getNodeList() {
		return Collections.unmodifiableMap(uris);
	}
	/**
	 * 自動領域拡張が可能なドメインかどうかを返す
	 * @return true:拡張可能 / false:拡張不可能
	 */
	public boolean isAutoExpandable() {
		return autoExpandable;
	}
	/**
	 * ドメインのハッシュコードを返す．
	 * ハッシュコードが同じであれば、同じ情報を持つことを意味する．
	 * @return ハッシュコード
	 */
	public int hashCode() {
		int hc = 11 * uris.size();
		int radix = 3;

		for(Iterator it = uris.keySet().iterator(); it.hasNext();) {
			String uri = (String)it.next();
			hc += radix * uri.hashCode();
			radix *= radix /2;
		}

		return hc;
	}

}
