diff src/treecms/memory/OnMemoryTreeEditor.java @ 7:fc19e38b669b

added concurrent access client for cassandr
author shoshi
date Thu, 17 Mar 2011 23:24:08 +0900
parents 12604eb6b615
children f96193babac0
line wrap: on
line diff
--- a/src/treecms/memory/OnMemoryTreeEditor.java	Mon Mar 14 23:24:38 2011 +0900
+++ b/src/treecms/memory/OnMemoryTreeEditor.java	Thu Mar 17 23:24:08 2011 +0900
@@ -4,100 +4,127 @@
 
 import treecms.api.Node;
 import treecms.api.NodeData;
+import treecms.api.NodeID;
 import treecms.api.TreeEditor;
 import treecms.merger.Merger;
 import treecms.merger.ReplaceMerger;
+import treecms.tree.util.NodePathFinder;
+import treecms.tree.util.PathNotFoundException;
 
-public class OnMemoryTreeEditor extends OnMemoryTree implements TreeEditor
+/**
+ * 木構造を非破壊的に編集するオンメモリの実装です。 
+ * @author shoshi
+ */
+final class OnMemoryTreeEditor implements TreeEditor
 {
-	OnMemoryTree m_tree;
-	OnMemoryNode m_oldRoot;
+	private OnMemoryTree m_tree;
+	private OnMemoryNode m_backup;
+	private OnMemoryNode m_root;
 	
-	public OnMemoryTreeEditor(OnMemoryForest _forest,OnMemoryTree _tree)
+	/**
+	 * コンストラクタです。
+	 * @param _tree 監視の対象とするOnMemoryTree
+	 */
+	public OnMemoryTreeEditor(OnMemoryTree _tree)
 	{
-		super(_tree.m_root,_forest);
-		m_oldRoot = m_root;
+		m_root = (OnMemoryNode)_tree.getRoot();
+		m_backup = m_root;
 	}
 	
+	/**
+	 * 変更を元の木構造にコミットします。この操作はコミット先が先にアップデートされていた場合は失敗します
+	 * @param _force trueの場合は強制的に置き換えます。
+	 * @return コミットが成功した場合true
+	 */
 	@Override
 	public boolean commit(boolean _force)
 	{
-		if(!check() || _force){
-			m_tree.m_root = m_root;
-		}
-		return false;
+		return m_tree.compareAndSwapRootNode(m_backup,m_root,_force);
 	}
 
+	/**
+	 * 監視している木構造のルートと自身のルートに上書きします。 
+	 * @return true
+	 */
 	@Override
 	public boolean pull()
 	{
-		m_root = m_tree.m_root;
+		m_root = (OnMemoryNode)m_tree.getRoot();
+		m_backup = m_root;
 		return true;
 	}
 
+	/**
+	 * 監視している木構造が更新されていないか確認します。
+	 * @return 更新されている場合true、されていない場合はfalse
+	 */
 	@Override
 	public boolean check()
 	{
-		if(m_tree.m_root.getID().equals(m_oldRoot.getID())){
+		if(m_tree.getRoot().getID().equals(m_root.getID())){
 			return false;
 		}
 		return true;
 	}
 
+	/**
+	 * 監視している木構造の内容を自分の木構造にマージします
+	 * 最新版の木構造とマージする場合は、先にpull()を実行してください。
+	 */
 	@Override
 	public void merge()
 	{
-		//call merger
 		Merger merger = new ReplaceMerger();
-		m_root = (OnMemoryNode)merger.merge(m_tree.m_root,m_root);
+		m_root = (OnMemoryNode)merger.merge(m_backup,m_root);
 	}
 	
+	/**
+	 * 木構造を非破壊的に更新します.
+	 * @param _target 更新する対象
+	 * @param _newData 更新に適用されるNodeData
+	 * @return 更新されたNode
+	 * @throws ルートNodeから_targetまでのパスが見つからない場合、PathNotFoundException
+	 */
 	@Override
-	public synchronized Node updateTree(Node _target,NodeData _newData)
+	public synchronized Node updateTree(Node _target,NodeData _newData) throws PathNotFoundException
 	{
-		LinkedList<OnMemoryNode> path = findAndClone(m_root,(OnMemoryNode)_target,_newData);
+		NodePathFinder finder = new NodePathFinder(m_root,_target);
+		OnMemoryForest forest = (OnMemoryForest)m_tree.getForest();
 		
-		if(path == null)
-		{
-			//not found.
-			return null;
+		for(Node path : finder){
+			NodeData data = path.getData();
+			NodeID newID = path.getID().update();
+			Node clone = forest.createNode(newID,data);
 		}
 		
-		m_root = path.peekFirst();
-		return path.peekLast();
+		return null;
 	}
 	
-	OnMemoryNode cloneNode(OnMemoryNode _target,NodeData _newData)
+	private LinkedList<OnMemoryNode> findAndClone(OnMemoryNode _parent,OnMemoryNode _target,NodeData _newData)
 	{
-		OnMemoryNode clone = m_forest.createNode(_target.getID().update(),_newData);
-		m_table.put(clone.getID().getUUID(),clone);
-		return clone;
-	}
-	
-	LinkedList<OnMemoryNode> findAndClone(OnMemoryNode _parent,OnMemoryNode _target,NodeData _newData)
-	{
-		if(_parent.getID().isFamily(_target.getID())){
-			//find.
+		OnMemoryForest forest = (OnMemoryForest)_target.getForest();
+		if(_parent.getID().equals(_target.getID())){
 			LinkedList<OnMemoryNode> path = new LinkedList<OnMemoryNode>();
-			OnMemoryNode clone = cloneNode((OnMemoryNode)_parent,_newData);
+			OnMemoryNode clone = forest.createNode(_target.getID().update(),_newData);
 			path.addFirst(clone);
 			return path;
 		}
 		
-		for(Node child : _parent.getData().list()){
+		for(Node child : _parent.children()){
 			LinkedList<OnMemoryNode> path = findAndClone((OnMemoryNode)child,_target,_newData);
 			if(path != null){
-				OnMemoryNode clone = cloneNode((OnMemoryNode)_parent,null);
-				clone.getData().list().remove(child);
-				clone.getData().list().add(path.peekFirst());
-				path.addFirst(clone);
+				path.addFirst(_parent);
 				return path;
 			}
 		}
 		
-		return null; //not found.
+		return null;
 	}
-
+	
+	/**
+	 * ルートNodeを取得します。
+	 * @return この木構造のルートNode
+	 * */
 	@Override
 	public Node getRoot()
 	{