・新しいサイトの探索を開始する際，全てのサイトに対するロックは必ず確保できる
ものとする．ロックはlockmgrを使ってnavigatorで管理される．

・同期処理は全て同期デーモンによって行われる．同期デーモンはスレッドである．

・同期デーモンは，上位ノードに対して前回配信したデータからの差分を転送し，
また自分のノード宛に上位ノードで発生した命令(主としてデータ削除命令)を
回収し，自分のノードに対して適用する．

・上位ノードに転送されたデータは，上位ノードでSyncQueueを使って管理される．
上位ノードは下位ノードの全てのデータを保有する．従って，上位にいくほど
データ保有量が多くなる．ここが問題の源泉となる場合がある．

・上位ノードでは，SyncQueueによって，下位ノードで情報が重複していないか
どうかを検査する．重複しているものについては，送信元のノードに対して，データを
削除する命令を発行する．

- - - - -

【遅延同期処理における重複検査法】

探索ロックなどの情報は，SyncQueueにおいて，宛先別に管理される．
Hashtable commands = (Hashtable)dic.( "node name" );
SyncCommand command = commands.get( "url" );
という具合だ．

たとえばあるURL，www.yahoo.co.jpが重複するかそうでないかを判定する場合，単純にループで
まわす．

boolean commandDuplicated = false;

SyncCommand[] list;
ArrayList rejectedCommands = new ArrayList();

for( int j = 0; j < list.length; j++ ) {
	synchronized( dic ) {
		Iterator i = dic.iterator();
		while( i.hasNext() ) {
			Hashtable commands = (Hashtable)i.next();
			SyncCommand command = (SyncCommand)commands.get( "www.yahoo.co.jp" );
			if( command != null ) {
				// あった
				commandDuplicated = true;
				break;
			} else {
				// なかったので登録する
				commands.put( "www.yahoo.co.jp", list[j] );
			}
		}
	}
	if( commandDuplicated ) {
		// 重複削除命令を発行する
		rejectedCommands.add( new SyncQueue( ... ) );
	}
}

遅延同期の仕組みでは，あるノードは直下のノード以外管理しない．
通常あるノードに接続される下位ノードは，100件を超えることがない．
また，hashによる検索はなかなか高速であることから，このアルゴリズムで問題ないかと思われる．


予想されるリスク
・下位ノードの数が極端に多くなった場合
・一度に転送される差分情報の数が，非常に多くなった場合
・synchronizedブロック


------------------------

LOCKがきた場合：
	同じのが既にあったら，削除命令に変換して送信元へ戻す

UNLOCKがきた場合：
	ロック情報が既に存在している場合，キューから削除して，UNLOCKを残す
	→ UNLOCKを上位のノードへ送信する必要があるため

FORWARD_URLがきた場合：
	同じURLがあった場合，削除命令に変換して送信元へ戻す

UNFORWARD_URLがきた場合：
	同じURLがきた場合，キューから削除して，UNFORWARD_URLを残す
	→ UNFORWARD_URLを上位のノードへ送信する必要があるため．
