changeset 12:fbbb7e414346

modified OnMemoryNode,OnMemoryTreeNode,OnMemoryMonotonicTreeNode
author shoshi
date Wed, 11 May 2011 03:34:01 +0900
parents 85061e874775
children c8601b0fa8a3
files CHANGELOG src/treecms/api/MonotonicTreeNode.java src/treecms/api/Node.java src/treecms/api/NodeData.java src/treecms/api/TreeNode.java src/treecms/memory/OnMemoryMonotonicTreeNode.java src/treecms/memory/OnMemoryNode.java src/treecms/memory/OnMemoryTree.java src/treecms/memory/OnMemoryTreeNode.java
diffstat 9 files changed, 648 insertions(+), 302 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG	Fri May 06 00:42:57 2011 +0900
+++ b/CHANGELOG	Wed May 11 03:34:01 2011 +0900
@@ -25,16 +25,36 @@
 
 	
 TODO
+
+2011-05-10
+	MonotonicTreeNodeのAPI合わせをやった.
+	OnMemoryの実装に移ろう.実際はOnMemoryがキャッシュとして使いやすいようにしないといけないんだけどな.AbstractHogehogeとかみたいに,
+	フレームワーク的に使いたいね.
+
+2011-05-09
+	Node自体はSingleLinkedNodeである,あるNodeを頂点とするTreeを作ることで、SingleLinkedNodeをラップしたDoubleLinkedNodeを作る.
+	これをTreeNodeとする.
+	Nodeからchildrenをとるときは防御的コピーをしよう.
+	いろいろと気にし過ぎな気もする
+	
+	NodeDataを実装に合わせた.
+	次はTreeNodeをあわせていくといいと思う.
+
+2011-05-07
+	Nodeの子供Listは重複要素を許可しないリストなので、NodeData、SetUniqueListにする。
+	NodeDataをSetUniqueListに変更した。
+	NodeDataってtreecms.apiよりはtreecms.utilの方なんじゃないかと思う、なので移動します。
 	
 2011-05-05
 	APIを変更した、ノードを表すクラスは[Node,TreeNode,MonotonicTreeNode]の3つで,TreeNodeとMonotonicTreeNodeはNodeを継承しない。
 	TreeNodeとMonotonicTreeNodeもノードを表すクラスの一つであるが,継承ではなくNodeを内部にメンバーとして持つ,
 	
 	問題点は,TreeNodeとMonotonicTreeNodeのメソッドをNodeとAPIの定義を用いて一致させたいが出来ない,NodeのAPIを変更するときには3つ全部書き換える必要がある.
+	Genericsを使って無理やり出来る方法を考えたが、まあどうだろう・・・
 	
 	現段階でNodeのメソッドは
-		属性関係が get,getAll,put,putAll,remove,removeAll
-		子供関係が add,addAll
+		属性関係が get,getAll,put,putAll,remove,removeAll,clear
+		子供関係が getChildren,addChild,addChildren,removeChild,removeChildren,clearChildren
 		その他 getID
 	
 	これをinterface Nodeに記述しておいた.TreeNodeとMonotonicTreeNode interfaceの変更が必要.
\ No newline at end of file
--- a/src/treecms/api/MonotonicTreeNode.java	Fri May 06 00:42:57 2011 +0900
+++ b/src/treecms/api/MonotonicTreeNode.java	Wed May 11 03:34:01 2011 +0900
@@ -1,20 +1,44 @@
 package treecms.api;
 
 import java.nio.ByteBuffer;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
+/**
+ * NodeのDoubleLinkedな実装です.SingleLinkedとは違いNodeの親情報まで保持します.
+ * TreeNodeとは違い、この実装は木を非破壊的に編集します.
+ * @author shoshi
+ */
 public interface MonotonicTreeNode
 {
-	public NodeID getID();
-	
+	/*
+	 * 属性関連のメソッド
+	 */
 	public ByteBuffer get(ByteBuffer _key);
 	public Map<ByteBuffer,ByteBuffer> getAll();
 	public void put(ByteBuffer _key,ByteBuffer _value);
 	public void putAll(Map<ByteBuffer,ByteBuffer> _map);
-	public void add(TreeNode _n);
-	public void addAll(List<TreeNode> _list);
+	public void remove(ByteBuffer _key);
+	public void removeAll(Set<ByteBuffer> _keys);
+	public void clear();
 	
+	/*
+	 * 子供関連のメソッド 
+	 */
+	public Iterator<MonotonicTreeNode> getChildren();
+	public void addChild(MonotonicTreeNode _n);
+	public void addChildren(List<MonotonicTreeNode> _list);
+	public void removeChild(MonotonicTreeNode _n);
+	public void removeChildren(List<MonotonicTreeNode> _list);
+	public void clearChildren();
+	
+	/*
+	 * 親関連のメソッド
+	 */
+	public NodeID getID();
+	public Forest getForest();
 	public MonotonicTreeNode getParent();
-	public TreeNode getNode();
+	public Node getNode();
 }
--- a/src/treecms/api/Node.java	Fri May 06 00:42:57 2011 +0900
+++ b/src/treecms/api/Node.java	Wed May 11 03:34:01 2011 +0900
@@ -1,12 +1,20 @@
 package treecms.api;
 
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.nio.ByteBuffer;
 
 /**
  * 木構造の基本のデータ単位であるNodeを示します.Nodeは子供のリストとデータのマップを保持します.また,クライアントはノードが保持しているデータをNodeDataとして
  * 取得することが出来ます.
+ * 
+ * NodeはSingleLinkで子供Nodeへのパスしか保持していません、どのNodeが親かどうか判断するのは不可能です.
+ * このようにしたのは,非破壊的木構造を実装するに当たり,編集対象のNodeの親を検索するのが困難であるからです.
+ * DoubleLinkな実装はTree/MonotonicTreeで行います.
+ * 
+ * また,重複した子供を追加することは出来ません,このインターフェイスを実装するクラスはそのように実装します.
  * @author shoshi
  */
 public interface Node
@@ -19,6 +27,7 @@
 	
 	/**
 	 * Nodeが保持するデータを取得します.クライアントはこのメソッドを用いて取得されるNodeDataを用いてNodeの内容を<b>変更できません</b>。
+	 * 変更を加えた場合は無視されるか、例外が発生します.
 	 * @return Nodeが保持するNodeData
 	 */
 	public NodeData getData();
@@ -29,17 +38,10 @@
 	 */
 	public Forest getForest();
 	
-	/**
-	 * 子供Nodeのリストを取得します..
-	 * @return 子供Nodeのリスト
+	/*
+	 * 属性関連のメソッド
+	 * get,getAll,put,putAll,remove,removeAll,clear
 	 */
-	public List<Node> children();
-	
-	/**
-	 * このNodeが保持するデータをマップとしてすべて取得します.
-	 * @return Nodeが保持するすべてのデータのマップ
-	 */
-	public Map<ByteBuffer,ByteBuffer> getAll();
 	
 	/**
 	 * このNodeが保持する値の中で指定されたキーと対応する値を取得します.
@@ -49,28 +51,10 @@
 	public ByteBuffer get(ByteBuffer _key);
 	
 	/**
-	 * 指定されたリストに含まれるNodeを,すべて子供Nodeとして追加します.
-	 * @param _children 追加される子供Nodeを保持するリスト
-	 */
-	public void addAll(List<Node> _children);
-	
-	/**
-	 * 指定されたNodeを子供Nodeとして追加します.
-	 * @param _child
+	 * このNodeが保持するデータをマップとしてすべて取得します.
+	 * @return Nodeが保持するすべてのデータのマップ
 	 */
-	public void add(Node _child);
-	
-	/**
-	 * 指定されたNodeを削除します。
-	 * @param _child
-	 */
-	public void remove(Node _child);
-	
-	/**
-	 * 指定した子供を全て削除します.
-	 * @param _children 削除される子供
-	 */
-	public void removeAll(List<Node> _children);
+	public Map<ByteBuffer,ByteBuffer> getAll();
 	
 	/**
 	 * キーとそれに対応する値を保存します.キーが重複した場合は上書きされます.
@@ -80,14 +64,66 @@
 	public void put(ByteBuffer _key,ByteBuffer _value);
 	
 	/**
+	 * キーとそれに対応する値を複数保持するマップを引数としてとり,マップが保持する値をすべて追加します.
+	 * @param _map 追加される値のマップ
+	 */
+	public void putAll(Map<ByteBuffer,ByteBuffer> _map);
+	
+	/**
 	 * キーとそれに対応する値を削除します。
 	 * @param _key キー
 	 */
 	public void remove(ByteBuffer _key);
 	
 	/**
-	 * キーとそれに対応する値を複数保持するマップを引数としてとり,マップが保持する値をすべて追加します.
-	 * @param _map 追加される値のマップ
+	 * Keyの集合すべてを削除します.
+	 * @param _key
+	 */
+	public void removeAll(Set<ByteBuffer> _key);
+	
+	/**
+	 * Keyの集合全てを削除します.
+	 */
+	public void clear();
+	
+	/*
+	 * 子供関連
+	 * getChildren,addChild,addChildren,removeChild,removeChildren,clearChildren
+	 */
+	
+	/**
+	 * 子供のIteratorを取得します.このIteratorは編集するためのメソッドは実装しません.
+	 * 呼び出した場合は例外は発生します.
+	 * @return 子供NodeのIterator
+	 */
+	public Iterator<Node> getChildren();
+	
+	/**
+	 * 指定されたNodeを子供Nodeとして追加します.
+	 * @param _child
 	 */
-	public void putAll(Map<ByteBuffer,ByteBuffer> _map);
-}
\ No newline at end of file
+	public void addChild(Node _child);
+	
+	/**
+	 * 指定されたリストに含まれるNodeを,すべて子供Nodeとして追加します.
+	 * @param _children 追加される子供Nodeを保持するリスト
+	 */
+	public void addChildren(List<Node> _children);
+	
+	/**
+	 * 指定されたNodeを削除します。
+	 * @param _child
+	 */
+	public void removeChild(Node _child);
+	
+	/**
+	 * 指定した子供を全て削除します.
+	 * @param _children 削除される子供
+	 */
+	public void removeChildren(List<Node> _children);
+	
+	/**
+	 * 全ての子供を削除します. 
+	 */
+	public void clearChildren();
+}
--- a/src/treecms/api/NodeData.java	Fri May 06 00:42:57 2011 +0900
+++ b/src/treecms/api/NodeData.java	Wed May 11 03:34:01 2011 +0900
@@ -1,28 +1,35 @@
 package treecms.api;
 
 import java.nio.ByteBuffer;
+
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
+import org.apache.commons.collections.list.SetUniqueList;
 
 /**
- * Nodeが保持するデータの集合です.Nodeを大きく変更するときや新しく作成される場合に使用されます.
- * 通常このクラスのインスタンスをNodeから取得した場合,NodeDataインスタンスに変更(set,add)を加えても元のNodeに変更は反映されません.
+ * Node が保持するデータのスナップショットです.Node を大きく変更するときや新しく作成される場合に使用されます.
+ * 通常このクラスのインスタンスを Node から取得した場合,NodeData インスタンスに変更(set,add)を加えても元の Node に変更は反映されません.
  * その様に実装してください.
+ * 
+ * このクラスは Node が保持するデータのうち 子供ノードのリスト・属性のマップ のみ保持しています.つまり,ノードが持っているはずの ID は保持していません.
+ * getID,getForest を呼び出すと UnsupportedOperationException をスローします.
  * @author shoshi
  */
 public final class NodeData implements Node
 {
 	/**
-	 * 子供Nodeのリスト
+	 * 子供 Node の List
+	 * 子供 Node の List は重複する Node を許可しない.
 	 */
 	private List<Node> m_children;
 	
 	/**
-	 * キーと対応する値のマップ
+	 * Key と対応する Value の Map
 	 */
 	private Map<ByteBuffer,ByteBuffer> m_attrs;
 	
@@ -35,154 +42,141 @@
 	}
 	
 	/**
-	 * コピーコンストラクタです.NodeDataの内容を防御的にコピーします.
+	 * コピーコンストラクタです.
+	 * NodeData の内容を防御的にコピーします.
 	 * @param _data
 	 */
 	public NodeData(NodeData _data)
 	{
 		if(_data != null){
-			m_children = new CopyOnWriteArrayList<Node>(_data.m_children);
-			m_attrs = new ConcurrentHashMap<ByteBuffer,ByteBuffer>(_data.m_attrs);
+			// SetUniqueList を使用することにより,List の重複要素を許可しない.
+			m_children = SetUniqueList.decorate(_data.m_children);
+			m_attrs = new HashMap<ByteBuffer,ByteBuffer>(_data.m_attrs);
 			return;
 		}
-		m_children = new CopyOnWriteArrayList<Node>();
-		m_attrs = new ConcurrentHashMap<ByteBuffer,ByteBuffer>();
+		m_children = SetUniqueList.decorate(new ArrayList<Node>());
+		m_attrs = new HashMap<ByteBuffer,ByteBuffer>();
 	}
 	
 	/**
 	 * 内部でコピーコンストラクタを呼び出します.
-	 * @return このNodeDataのコピー
+	 * @return この NodeData のコピー
 	 */
 	public NodeData deepCopy()
 	{
 		return new NodeData(this);
 	}
 	
-	/**
-	 * キーのセットを取得します.
-	 * @return キーのセット
-	 */
-	public Set<ByteBuffer> keySet()
-	{
-		return m_attrs.keySet();
-	}
-	
-	/**
-	 * キーに対応する値を取得します. 
-	 * @param _name
-	 * @return キーに対応する値
-	 */
-	public ByteBuffer get(ByteBuffer _name)
-	{
-		return m_attrs.get(_name);
-	}
-	
-	/**
-	 * キーとそれに対応する値を追加します.
-	 * @param _name キー
-	 * @param _value 値
-	 */
-	public void put(ByteBuffer _name,ByteBuffer _value)
-	{
-		m_attrs.put(_name,_value);
-	}
-	
-	/**
-	 * キーとその対応する値をマップから削除します
-	 * @param _name
-	 */
-	public void remove(ByteBuffer _name)
-	{
-		m_attrs.remove(_name);
-	}
-	
-	/**
-	 * キーとそれに対応する値のマップ全体を追加します.
-	 * @param _map
-	 */
-	public void putAll(Map<ByteBuffer,ByteBuffer> _map)
-	{
-		m_attrs.putAll(_map);
-	}
-	
-	/**
-	 * 子供Nodeのリストを取得します.<br/>
-	 * この取得されたリストは編集できません.編集はadd,addAllより行ってください.
-	 * @return 子供Nodeのリスト
-	 */
-	public List<Node> children()
-	{
-		return Collections.unmodifiableList(m_children);
-	}
-	
-	/**
-	 * 子供Nodeを追加します.
-	 * @param _child
-	 */
-	public void add(Node _child)
-	{
-		m_children.add(_child);
-	}
-	
-	/**
-	 * 子供Nodeリスト全部を子供Nodeとして追加します.
-	 * @param _child
-	 */
-	public void addAll(List<Node> _child)
-	{
-		m_children.addAll(_child);
-	}
-	
-	/**
-	 * 指定されたNodeを子供Nodeのリストから削除します.
-	 * @param _child
-	 */
-	public void remove(Node _child)
-	{
-		m_children.remove(_child);
-	}
-	
-	/**
-	 * 指定されたNodeのリストに含まれるすべてのNodeを子供Nodeのリストから削除します.
-	 * @param _child
-	 */
-	public void removeAll(List<Node> _child)
-	{
-		m_children.removeAll(_child);
-	}
-	
-	/**
-	 * NodeDataが保持しているすべてのキーと値の組のマップを返します.
-	 * @return すべてのキーと値のマップ
-	 */
-	public Map<ByteBuffer,ByteBuffer> getAll()
-	{
-		return Collections.unmodifiableMap(m_attrs);
-	}
-	
-	/**
-	 * 子供Nodeのリストをクリアします.(すべて削除します.)
-	 */
-	public void clear()
-	{
-		m_children.clear();
-	}
-
 	@Override
 	public NodeID getID()
 	{
+		//このクラスはデータのみ保持する.
 		return null;
 	}
 
 	@Override
 	public NodeData getData()
 	{
-		return this;
+		return new NodeData(this);
 	}
 
 	@Override
 	public Forest getForest()
 	{
+		//このクラスはデータのみ保持する.
 		return null;
 	}
+	
+	/*
+	 * 属性関連
+	 */
+	
+	public Set<ByteBuffer> keySet()
+	{
+		return m_attrs.keySet();
+	}
+	
+	@Override
+	public ByteBuffer get(ByteBuffer _name)
+	{
+		return m_attrs.get(_name);
+	}
+	
+	@Override
+	public Map<ByteBuffer,ByteBuffer> getAll()
+	{
+		return Collections.unmodifiableMap(this.m_attrs);
+	}
+	
+	@Override
+	public void put(ByteBuffer _name,ByteBuffer _value)
+	{
+		m_attrs.put(_name,_value);
+	}
+	
+	@Override
+	public void putAll(Map<ByteBuffer,ByteBuffer> _map)
+	{
+		m_attrs.putAll(_map);
+	}
+	
+	@Override
+	public void remove(ByteBuffer _name)
+	{
+		m_attrs.remove(_name);
+	}
+	
+	@Override
+	public void removeAll(Set<ByteBuffer> _keySet)
+	{
+		for(ByteBuffer _key : _keySet){
+			m_attrs.remove(_key);
+		}
+	}
+	
+	@Override
+	public void clear()
+	{
+		m_attrs.clear();
+	}
+	
+	/*
+	 * 子供関連
+	 */
+	
+	@Override
+	public Iterator<Node> getChildren()
+	{
+		return Collections.unmodifiableList(m_children).iterator();
+	}
+	
+	@Override
+	public void addChild(Node _child)
+	{
+		m_children.add(_child);
+	}
+	
+	@Override
+	public void addChildren(List<Node> _child)
+	{
+		m_children.addAll(_child);
+	}
+	
+	@Override
+	public void removeChild(Node _child)
+	{
+		m_children.remove(_child);
+	}
+	
+	@Override
+	public void removeChildren(List<Node> _child)
+	{
+		m_children.removeAll(_child);
+	}
+	
+	@Override
+	public void clearChildren()
+	{
+		m_children.clear();
+	}
 }
--- a/src/treecms/api/TreeNode.java	Fri May 06 00:42:57 2011 +0900
+++ b/src/treecms/api/TreeNode.java	Wed May 11 03:34:01 2011 +0900
@@ -1,25 +1,50 @@
 package treecms.api;
 
 import java.nio.ByteBuffer;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
+/**
+ * DoubleLinkedなNodeの実装です.SingleLinkedなNodeの実装と違い,親の情報を保持します.
+ * 非破壊的木構造の実装では,Nodeは子どもの情報しか持っていません.これは,一つのNodeに対して複数の親が存在するためです.
+ * 木構造内のあるNodeへのRootNodeからのパスを検索する手間を省くことが出来ます.
+ * 
+ * なのでSingleLinkedとDoubleLinkedを分けて,DoubleLinkedはSingleLinkedを内包した形で実装します.
+ * TreeNodeがNodeのインターフェイスを継承していないのは,継承するとSingleLinkedなNodeに子供として追加できるようになるからです.
+ * 
+ * また,TreeNodeを編集したときは非破壊的に編集されず、破壊的に編集されます.
+ * @author shoshi
+ */
 public interface TreeNode
 {
-	public NodeID getID();
-	
+	/*
+	 * 属性関連のメソッド
+	 */
 	public ByteBuffer get(ByteBuffer _key);
 	public Map<ByteBuffer,ByteBuffer> getAll();
 	public void put(ByteBuffer _key,ByteBuffer _value);
 	public void putAll(Map<ByteBuffer,ByteBuffer> _map);
 	public void remove(ByteBuffer _key);
-	public void removeKeys(List<ByteBuffer> _keys);
+	public void removeAll(Set<ByteBuffer> _keys);
+	public void clear();
 	
-	public void add(TreeNode _n);
-	public void addAll(List<TreeNode> _list);
-	public void remove(TreeNode _n);
-	public void removeAll(List<TreeNode> _list);
+	/*
+	 * 子供関連のメソッド 
+	 */
+	public Iterator<TreeNode> getChildren();
+	public void addChild(TreeNode _n);
+	public void addChildren(List<TreeNode> _list);
+	public void removeChild(TreeNode _n);
+	public void removeChildren(List<TreeNode> _list);
+	public void clearChildren();
 	
+	/*
+	 * 親関連のメソッド
+	 */
+	public NodeID getID();
+	public Forest getForest();
 	public TreeNode getParent();
 	public Node getNode();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/treecms/memory/OnMemoryMonotonicTreeNode.java	Wed May 11 03:34:01 2011 +0900
@@ -0,0 +1,206 @@
+package treecms.memory;
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import treecms.api.Forest;
+import treecms.api.MonotonicTreeNode;
+import treecms.api.Node;
+import treecms.api.NodeID;
+import treecms.api.TreeNode;
+
+/**
+ * SingleLinkedなNodeをラップしたDoubleLinkedなNodeの実装です.
+ * @author shoshi
+ */
+public class OnMemoryMonotonicTreeNode implements MonotonicTreeNode
+{
+	private OnMemoryMonotonicTree m_tree;
+	private OnMemoryNode m_node;
+	private OnMemoryMonotonicTreeNode m_parent;
+	
+	/**
+	 * コンストラクタです.
+	 * @param _target 対象となるSingleLinked Node
+	 * @param _parent このDoubleLinked Nodeの親,RootNodeならnull
+	 * @param _tree このNodeがRootNodeなら,nullではいけない.
+	 */
+	public OnMemoryMonotonicTreeNode(OnMemoryNode _target,OnMemoryMonotonicTreeNode _parent,OnMemoryMonotonicTree _tree)
+	{
+		if(_target == null){
+			throw new NullPointerException("_target must not be null.");
+		}
+		
+		if(_parent == null && _tree == null){
+			throw new NullPointerException("_parent or _tree must not be null.");
+		}
+		
+		m_node  = _target;
+		m_parent = _parent;
+		m_tree = _tree;
+	}
+	
+	/*
+	 * 親関連のメソッド
+	 */
+	
+	@Override
+	public NodeID getID()
+	{
+		return m_node.getID();
+	}
+
+	@Override
+	public Forest getForest()
+	{
+		return m_node.getForest();
+	}
+
+	@Override
+	public MonotonicTreeNode getParent()
+	{
+		return m_parent;
+	}
+
+	@Override
+	public Node getNode()
+	{
+		return m_node;
+	}
+	
+	/*
+	 * 属性関連のメソッド
+	 */
+	
+	@Override
+	public ByteBuffer get(ByteBuffer _key)
+	{
+		return m_node.get(_key);
+	}
+
+	@Override
+	public Map<ByteBuffer, ByteBuffer> getAll()
+	{
+		return m_node.getAll();
+	}
+
+	@Override
+	public void put(ByteBuffer _key, ByteBuffer _value)
+	{
+		m_node.put(_key,_value);
+	}
+
+	@Override
+	public void putAll(Map<ByteBuffer, ByteBuffer> _map)
+	{
+		m_node.putAll(_map);
+	}
+
+	@Override
+	public void remove(ByteBuffer _key)
+	{
+		m_node.remove(_key);
+	}
+
+	@Override
+	public void removeAll(Set<ByteBuffer> _keys)
+	{
+		m_node.removeAll(_keys);
+	}
+
+	@Override
+	public void clear()
+	{
+		m_node.clear();
+	}
+	
+	/**
+	 * このMonotonicNodeに変更が加えられたら,こちらのメソッドが呼び出されます.
+	 * このメソッドでは非破壊的に変更するために,SingleLinkedNodeのクローンを作成し,
+	 * 親にも複製を依頼します.
+	 * 
+	 * RootNodeまで伝搬すると親のNodeはnullとなる.親Nodeは担当するMonotonicTreeのオブジェクトを保持しており,そこにRootNodeが変更されたことを通知する.
+	 * 通知が終わり,処理が戻ってきた時に自身のOnMemoryNodeをクローンした新しいものに書き換えます.
+	 * 
+	 * _fromがnullの場合は,自身が編集元であることを示します.
+	 * @param _from 編集元のOnMemoryMonotonicTreeNode
+	 */
+	public void cloneAndTransmit(OnMemoryNode _from)
+	{
+		OnMemoryNode clone = m_node.cloneNode();
+		if(m_parent != null){
+			//親が存在する,親に変更があったことを伝搬する.
+			m_parent.cloneAndTransmit(clone);
+		}else{
+			//何かすることはないかな
+		}
+		
+		//編集終了
+		m_node = clone;
+	}
+	
+	/*
+	 * 子供関連のメソッド
+	 */
+
+	@Override
+	public Iterator<MonotonicTreeNode> getChildren()
+	{
+		//NodeのリストよりMonotonicTreeNodeのリストを作成する.
+		LinkedList<MonotonicTreeNode> res = new LinkedList<MonotonicTreeNode>();
+		for(Iterator<Node> it = m_node.getChildren();it.hasNext();){
+			OnMemoryNode n = (OnMemoryNode)it.next();
+			res.add(new OnMemoryMonotonicTreeNode(n,this,null));
+		}
+		
+		return res.iterator();
+	}
+
+	@Override
+	public void addChild(MonotonicTreeNode _n)
+	{
+		m_node.addChild(_n.getNode());
+	}
+
+	@Override
+	public void addChildren(List<MonotonicTreeNode> _list)
+	{
+		//MotonicTreeNodeのリストからNodeのリストを作成する.
+		LinkedList<Node> res = new LinkedList<Node>();
+		for(Iterator<MonotonicTreeNode> it = _list.iterator();it.hasNext();){
+			MonotonicTreeNode mono = (MonotonicTreeNode)it.next();
+			res.add(mono.getNode());
+		}
+		
+		m_node.addChildren(res);
+	}
+
+	@Override
+	public void removeChild(MonotonicTreeNode _n)
+	{
+		m_node.removeChild(_n.getNode());
+	}
+
+	@Override
+	public void removeChildren(List<MonotonicTreeNode> _list)
+	{
+		//MonotonicTreeNodeのリスト
+		LinkedList<Node> res = new LinkedList<Node>();
+		for(Iterator<MonotonicTreeNode> it = _list.iterator();it.hasNext();){
+			MonotonicTreeNode mono = it.next();
+			res.add(mono.getNode());
+		}
+		
+		m_node.removeChildren(res);
+	}
+
+	@Override
+	public void clearChildren()
+	{
+		m_node.clearChildren();
+	}
+
+}
--- a/src/treecms/memory/OnMemoryNode.java	Fri May 06 00:42:57 2011 +0900
+++ b/src/treecms/memory/OnMemoryNode.java	Wed May 11 03:34:01 2011 +0900
@@ -1,8 +1,11 @@
 package treecms.memory;
 
 import java.nio.ByteBuffer;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+
 import treecms.api.Forest;
 import treecms.api.Node;
 import treecms.api.NodeData;
@@ -20,7 +23,7 @@
 	private NodeData m_data;
 	
 	/**
-	 * コンストラクタです.
+	 * コンストラクタ
 	 * @param _forest このNodeが属するForestです.
 	 * @param _id このNodeのNodeIDです.
 	 * @param _newData このNodeに割り当てるNodeDataです.防御的にコピーします.
@@ -32,122 +35,97 @@
 		m_data = (_newData != null) ? _newData.deepCopy() : new NodeData();
 	}
 	
-	/**
-	 * Nodeが属するForestを取得します.
-	 * @return Nodeが属するForest
+	/*
+	 * Nodeの情報関連
 	 */
+	
 	@Override
 	public Forest getForest()
 	{
 		return m_forest;
 	}
 	
-	/**
-	 * Nodeに対応するNodeIDを取得します.
-	 * @return Nodeに対応するNodeID
-	 */
 	@Override
 	public NodeID getID()
 	{
 		return m_id;
 	}
 
-	/**
-	 * Nodeが保持するデータを取得します.クライアントはこのメソッドを用いて取得されるNodeDataを用いてNodeの内容を<b>変更できません</b>。
-	 * @return Nodeが保持するNodeData
-	 */
 	@Override
 	public NodeData getData()
 	{
 		return m_data.deepCopy();
 	}
-
-	/**
-	 * 指定されたNodeを子供Nodeとして追加します.
-	 * @param _child
+	
+	/*
+	 * 子供関連のメソッド
 	 */
+	
 	@Override
-	public void add(Node _child)
+	public Iterator<Node> getChildren()
 	{
-		m_data.add(_child);
-	}
-	
-	/**
-	 * 子供Nodeを削除します。
-	 * @param _child
-	 */
-	@Override
-	public void remove(Node _child)
-	{
-		m_data.remove(_child);
+		//Iteratorが変更不可なので、そのまま渡しても構わない
+		return m_data.getChildren();
 	}
 
-	/**
-	 * 指定されたリストに含まれるNodeを,すべて子供Nodeとして追加します.
-	 * @param _children 追加される子供Nodeを保持するリスト
-	 */
+	@Override
+	public void addChild(Node _child)
+	{
+		m_data.addChild(_child);
+	}
+	
+	@Override
+	public void addChildren(List<Node> _child)
+	{
+		m_data.addChildren(_child);
+	}
+	
 	@Override
-	public void addAll(List<Node> _children)
+	public void removeChild(Node _child)
+	{
+		m_data.removeChild(_child);
+	}
+	
+	@Override
+	public void removeChildren(List<Node> _children)
 	{
-		m_data.addAll(_children);
+		m_data.removeChildren(_children);
+	}
+	
+	@Override
+	public void clearChildren()
+	{
+		m_data.clearChildren();
 	}
 
-	/**
-	 * 子供Nodeのリストを取得します..
-	 * @return 子供Nodeのリスト
+	/*
+	 * 要素関連のメソッド
 	 */
-	@Override
-	public List<Node> children()
-	{
-		return m_data.children();
-	}
 
-	/**
-	 * このNodeが保持する値の中で指定されたキーと対応する値を取得します.
-	 * @param _key データに対応するキー
-	 * @return キーと対応する値,見つからない場合はnull
-	 */
 	@Override
 	public ByteBuffer get(ByteBuffer _key)
 	{
 		return m_data.get(_key);
 	}
 
-	/**
-	 * このNodeが保持するデータをマップとしてすべて取得します.
-	 * @return Nodeが保持するすべてのデータのマップ
-	 */
 	@Override
 	public Map<ByteBuffer,ByteBuffer> getAll()
 	{
 		return m_data.getAll();
 	}
 
-	/**
-	 * キーとそれに対応する値を保存します.キーが重複した場合は上書きされます.
-	 * @param _key キー
-	 * @param _value 値
-	 */
 	@Override
 	public void put(ByteBuffer _key, ByteBuffer _value)
 	{
 		m_data.put(_key,_value);
 	}
 
-	/**
-	 * キーとそれに対応する値を複数保持するマップを引数としてとり,マップが保持する値をすべて追加します.
-	 * @param _map 追加される値のマップ
-	 */
 	@Override
 	public void putAll(Map<ByteBuffer, ByteBuffer> _map)
 	{
 		m_data.putAll(_map);
 	}
 
-	/**
-	 * キーとそれに対応する値を削除します。
-	 * @param _key キー
-	 */
 	@Override
 	public void remove(ByteBuffer _key)
 	{
@@ -155,6 +133,24 @@
 	}
 	
 	@Override
+	public void removeAll(Set<ByteBuffer> _keySet)
+	{
+		m_data.removeAll(_keySet);
+	}
+	
+	@Override
+	public void clear()
+	{
+		m_data.clear();
+	}
+	
+	@Override
+	public int hashCode()
+	{
+		return m_id.hashCode();
+	}
+	
+	@Override
 	public String toString()
 	{
 		return getID().toString();
--- a/src/treecms/memory/OnMemoryTree.java	Fri May 06 00:42:57 2011 +0900
+++ b/src/treecms/memory/OnMemoryTree.java	Wed May 11 03:34:01 2011 +0900
@@ -1,15 +1,6 @@
 package treecms.memory;
 
-import java.nio.ByteBuffer;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-
-import treecms.api.Forest;
-import treecms.api.Node;
-import treecms.api.NodeData;
-import treecms.api.NodeID;
 import treecms.api.Tree;
 import treecms.api.TreeNode;
 
--- a/src/treecms/memory/OnMemoryTreeNode.java	Fri May 06 00:42:57 2011 +0900
+++ b/src/treecms/memory/OnMemoryTreeNode.java	Wed May 11 03:34:01 2011 +0900
@@ -1,26 +1,34 @@
 package treecms.memory;
 
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-
-import org.apache.commons.collections.list.SetUniqueList;
-
+import java.util.Set;
 import treecms.api.Forest;
 import treecms.api.Node;
-import treecms.api.NodeData;
 import treecms.api.NodeID;
-import treecms.api.SingleNode;
 import treecms.api.TreeNode;
 
+/**
+ * DoubleLinkedなNodeであるTreeNodeのOnMemory実装です. 
+ * @author shoshi
+ */
 public class OnMemoryTreeNode implements TreeNode
 {
 	public OnMemoryTreeNode m_parent;
 	public OnMemoryNode m_node;
 	
+	/**
+	 * コンストラクタです.
+	 * @param _node 対象となるSingleLinkedなNode
+	 * @param _parent 親のOnMemoryTreeNode
+	 */
 	public OnMemoryTreeNode(OnMemoryNode _node,OnMemoryTreeNode _parent)
 	{
+		//とりあえず、チェック
 		if(_node == null){
 			throw new NullPointerException();
 		}
@@ -31,38 +39,106 @@
 		m_parent = _parent;
 	}
 	
+	/*
+	 * 親関連のメソッド
+	 */
+	
 	@Override
 	public NodeID getID()
 	{
 		return m_node.getID();
 	}
-
+	
 	@Override
-	public NodeData getData()
+	public Node getNode()
 	{
-		return m_node.getData();
+		return m_node;
 	}
-
+	
+	@Override
+	public  TreeNode getParent()
+	{
+		return m_parent;
+	}
+	
 	@Override
 	public Forest getForest()
 	{
 		return m_node.getForest();
 	}
+	
+	/*
+	 * 子供関連のメソッド
+	 */
 
 	@Override
-	public List<Node> children()
+	public Iterator<TreeNode> getChildren()
 	{
 		/* 
-		 * TreeNodeの子TreeNodeリストを作成する.
 		 * m_node(対象ノード)のリストにはNodeが格納されており、TreeNodeのリストを取得するためにはTreeNodeで要素を構成する必要がある.
 		 */
-		List<Node> list = m_node.children();
-		ArrayList<Node> ret = new ArrayList<Node>(list.size());
-		for(Node n : list){
-			ret.add(new OnMemoryTreeNode((OnMemoryNode)n,this));
+		LinkedList<TreeNode> ret = new LinkedList<TreeNode>();
+		for(Iterator<Node> it = m_node.getChildren();it.hasNext();){
+			OnMemoryNode n = (OnMemoryNode)it.next();
+			ret.add(new OnMemoryTreeNode(n,this));
+		}
+		
+		return Collections.unmodifiableList(ret).iterator();
+	}
+	
+	@Override
+	public void addChild(TreeNode _child)
+	{
+		m_node.addChild(_child.getNode());
+	}
+
+	@Override
+	public void addChildren(List<TreeNode> _children)
+	{
+		/*
+		 * TreeNodeのリストからNodeのリストへ変換する
+		 */
+		LinkedList<Node> res = new LinkedList<Node>();
+		for(Iterator<TreeNode> it = _children.iterator();it.hasNext();){
+			TreeNode tn = it.next();
+			res.add(tn.getNode());
 		}
 		
-		return ret;
+		m_node.addChildren(res);
+	}
+	
+	@Override
+	public void removeChild(TreeNode _child)
+	{
+		m_node.removeChild(_child.getNode());
+	}
+	
+	@Override
+	public void removeChildren(List<TreeNode> _children)
+	{
+		LinkedList<Node> res = new LinkedList<Node>();
+		for(Iterator<TreeNode> it = _children.iterator();it.hasNext();){
+			TreeNode tn = it.next();
+			res.add(tn.getNode());
+		}
+		
+		m_node.removeChildren(res);
+	}
+	
+	@Override
+	public void clearChildren()
+	{
+		m_node.clearChildren();
+	}
+
+	/*
+	 * 属性関連のメソッド
+	 */
+	
+	@Override
+	public ByteBuffer get(ByteBuffer _key)
+	{
+		return m_node.get(_key);
 	}
 
 	@Override
@@ -72,54 +148,32 @@
 	}
 
 	@Override
-	public ByteBuffer get(ByteBuffer _key)
+	public void put(ByteBuffer _key,ByteBuffer _value)
 	{
-		return m_node.get(_key);
+		m_node.put(_key,_value);
 	}
-
-	@Override
-	public void addAll(List<Node> _children)
-	{
-	}
-
+	
 	@Override
-	public void add(Node _child) {
-		// TODO Auto-generated method stub
-		
+	public void putAll(Map<ByteBuffer,ByteBuffer> _map)
+	{
+		m_node.putAll(_map);
 	}
-
-	@Override
-	public void remove(Node _child) {
-		// TODO Auto-generated method stub
-		
-	}
-
+	
 	@Override
-	public void put(ByteBuffer _key, ByteBuffer _value) {
-		// TODO Auto-generated method stub
-		
-	}
-
-	@Override
-	public void remove(ByteBuffer _key) {
-	}
-
-	@Override
-	public void putAll(Map<ByteBuffer, ByteBuffer> _map) {
-		// TODO Auto-generated method stub
-		
+	public void remove(ByteBuffer _key)
+	{
+		m_node.remove(_key);
 	}
-
+	
 	@Override
-	public TreeNode getParent() {
-		// TODO Auto-generated method stub
-		return null;
+	public void removeAll(Set<ByteBuffer> _keySet)
+	{
+		m_node.removeAll(_keySet);
 	}
-
+	
 	@Override
-	public SingleNode getNode() {
-		// TODO Auto-generated method stub
-		return null;
+	public void clear()
+	{
+		m_node.clear();
 	}
-
 }