changeset 38:e647bb37b7ad

added treecms.proto.merge
author suika6039
date Thu, 30 Dec 2010 00:50:47 +0900
parents 78e9b96ef04a
children ea7f0a4eacaf
files src/treecms/proto/api/Editor.java src/treecms/proto/gui/GraphicalMonotonicTreeEditor.java src/treecms/proto/marge/Marger.java src/treecms/proto/marge/ReplaceMarger.java src/treecms/proto/simple/SimpleEditor.java src/treecms/proto/simple/SimpleNode.java src/treecms/proto/simple/test/SimpleEditorTest1.java src/treecms/proto/simple/test/SimpleEditorTest2.java src/treecms/proto/test/EditorTest.java src/treecms/proto/test/NodeTest.java src/treecms/proto/util/RandomSimpleTreeBuilder.java
diffstat 11 files changed, 195 insertions(+), 334 deletions(-) [+]
line wrap: on
line diff
--- a/src/treecms/proto/api/Editor.java	Wed Dec 29 03:13:18 2010 +0900
+++ b/src/treecms/proto/api/Editor.java	Thu Dec 30 00:50:47 2010 +0900
@@ -5,10 +5,21 @@
 	public void login(String user,String pass);
 	public void logout();
 	
+	//copy root to _target path and return clone of _target
 	public Node edit(Node _target);
+	
+	//commit local tree to remote tree
 	public boolean commit(boolean _force);
+	
+	//pull updates from remote tree
 	public boolean update();
+	
+	//check that is remote tree modified.
 	public boolean check();
+	
+	//merge remote tree to local tree
 	public void merge();
+	
+	//get uncommited (editting root)
 	public Node getUncommited();
 }
--- a/src/treecms/proto/gui/GraphicalMonotonicTreeEditor.java	Wed Dec 29 03:13:18 2010 +0900
+++ b/src/treecms/proto/gui/GraphicalMonotonicTreeEditor.java	Thu Dec 30 00:50:47 2010 +0900
@@ -1,10 +1,10 @@
 package treecms.proto.gui;
 
 import java.awt.BorderLayout;
+
 import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.util.concurrent.atomic.AtomicReference;
 
 import javax.swing.JButton;
 import javax.swing.JComponent;
@@ -25,8 +25,6 @@
 import treecms.proto.api.Editor;
 import treecms.proto.api.Node;
 import treecms.proto.simple.SimpleEditor;
-import treecms.proto.simple.SimpleNode;
-import treecms.proto.util.RandomSimpleTreeBuilder;
 
 public class GraphicalMonotonicTreeEditor extends JFrame
 {
@@ -34,10 +32,7 @@
 
 	public static void main(String _args[])
 	{
-		AtomicReference<Node> repo = new AtomicReference<Node>(RandomSimpleTreeBuilder.randomTree(2,2,3,3));
-		
-		new GraphicalMonotonicTreeEditor(new SimpleEditor(repo));
-		new GraphicalMonotonicTreeEditor(new SimpleEditor(repo));
+		new GraphicalMonotonicTreeEditor(new SimpleEditor());
 	}
 	
 	private static final String WINDOW_TITLE = "Monotonic-Tree Editor";
@@ -312,7 +307,7 @@
 			
 			if(source.equals(m_addButton)){
 				Node newNode = m_editor.edit(tableModel.getNode());
-				newNode.addChild(new SimpleNode());
+				newNode.addChild(newNode.createNode());
 				
 				ContentsViewerTreeModel treeModel = (ContentsViewerTreeModel)m_tree.getModel();
 				treeModel.setRootNode(m_editor.getUncommited(),true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/treecms/proto/marge/Marger.java	Thu Dec 30 00:50:47 2010 +0900
@@ -0,0 +1,8 @@
+package treecms.proto.marge;
+
+import treecms.proto.api.Node;
+
+public interface Marger
+{
+	public Node merge(Node _root1,Node _root2);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/treecms/proto/marge/ReplaceMarger.java	Thu Dec 30 00:50:47 2010 +0900
@@ -0,0 +1,14 @@
+package treecms.proto.marge;
+
+import treecms.proto.api.Node;
+
+public class ReplaceMarger implements Marger
+{
+
+	@Override
+	public Node merge(Node _from, Node _to)
+	{
+		return _from;
+	}
+
+}
--- a/src/treecms/proto/simple/SimpleEditor.java	Wed Dec 29 03:13:18 2010 +0900
+++ b/src/treecms/proto/simple/SimpleEditor.java	Thu Dec 30 00:50:47 2010 +0900
@@ -1,74 +1,75 @@
 package treecms.proto.simple;
 
 import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
+
 import java.util.LinkedList;
 import treecms.proto.api.Editor;
 import treecms.proto.api.Node;
+import treecms.proto.api.NodeID;
+import treecms.proto.marge.Marger;
+import treecms.proto.marge.ReplaceMarger;
 
 public class SimpleEditor implements Editor
 {
-	private AtomicReference<Node> m_repository;
+	private SimpleNode m_local;
+	private SimpleNode m_remote;
+	
+	private static final SimpleBrowser m_browser = SimpleBrowser.getSingleton();
 	
-	private Node m_uncommitted; // uncommitted version
-	private Node m_tip; // tip version
-	
-	private LinkedList<Pair<Node,Node>> m_editLog; // there is noting for it but to do.
+	public SimpleEditor()
+	{
+		update();
+	}
 	
-	public SimpleEditor(AtomicReference<Node> _contents)
+	public void copyNode(Node _from,Node _to)
 	{
-		m_repository = _contents;
-		m_tip = m_repository.get();
-		m_uncommitted = m_tip;
-		m_editLog = new LinkedList<Pair<Node,Node>>();
+		_to.setClassName(_from.getClassName());
+		_to.setTitle(_from.getTitle());
+		
+		for(String _key : _from.getAttributeKeys()){
+			_to.setAttribute(_key,_from.getAttribute(_key));
+		}
+		
+		_to.addChildren(_from.getChildren());
 	}
 	
 	@Override
 	public boolean check()
 	{
-		return !m_repository.compareAndSet(m_tip,m_tip); //CAS same value to check update.
+		NodeID remoteID = m_remote.getID();
+		if(remoteID.equals(remoteID.getTip())){
+			return false;
+		}
+		return true;
 	}
 	
 	public boolean commit(boolean _force)
 	{
-		if(_force){
-			m_repository.set(m_uncommitted); // force commit
-			update();
+		if(_force || !check()){
+			Node target = m_remote.cloneNode();
+			target.clearChildren();
+			copyNode(m_local,target);
 			return true;
 		}
 		
-		//will be success when nobody committed before.
-		return m_repository.compareAndSet(m_tip,m_uncommitted);
+		return false;
 	}
 	
 	public void merge()
 	{
-		LinkedList<Pair<Node,Node>> log = new LinkedList<Pair<Node,Node>>(m_editLog); //backup
-		
-		update();
-		for(Pair<Node,Node> pair: log){
-			Node target = pair.getLeft();
-			Node clone = pair.getRight();
-			Node newNode = edit(target); //edit again;
-			
-			//set parameters
-			newNode.setClassName(clone.getClassName());
-			newNode.setTitle(clone.getTitle());
-			newNode.clearChildren();
-		}
+		Marger marger = new ReplaceMarger();
+		m_local = (SimpleNode)marger.merge(m_remote,m_local);
 	}
 	
 	public void discard()
 	{
-		//delete all uncommitted changes.
-		m_uncommitted = m_tip;
-		m_editLog.clear();
+		copyNode(m_remote,m_local);
 	}
 
 	@Override
 	public Node useContents()
 	{
-		return m_uncommitted; 
+		return m_local;
 	}
 
 	@Override
@@ -84,22 +85,19 @@
 	@Override
 	public Node edit(Node _target)
 	{
-		LinkedList<Node> path = findPath(m_uncommitted,_target);
+		LinkedList<Node> path = findPath(m_local,_target);
 		if(path.isEmpty()){
 			return null;
 		}
 		
 		LinkedList<Node> change = new LinkedList<Node>();
-		Node root = path.poll().cloneNode();
+		SimpleNode root = (SimpleNode)path.poll().cloneNode();
 		change.add(root);
 		cloneTree(path,root,change);
 		
-		m_uncommitted = root;
+		m_local = root;
 		
 		Node clone = change.peekLast();
-		
-		m_editLog.add(new Pair<Node,Node>(_target,clone)); // left -> target , right -> clone
-		
 		return clone;
 	}
 	
@@ -112,7 +110,7 @@
 		}
 		for(int i = 0;i < children.size();i ++){
 			Node _child = children.get(i);
-			if(_child.getID().compare(target.getID()) != -2){
+			if(_child.getID().isFamily(target.getID())){
 				//clone node
 				Node clone = _child.cloneNode();
 				_change.add(clone);
@@ -137,7 +135,7 @@
 	
 	private boolean findPath(Node _root,Node _child,LinkedList<Node> _list)
 	{
-		if(_root.getID().compare(_child.getID()) != -2){
+		if(_root.getID().isFamily(_child.getID())){
 			return true;
 		}
 		
@@ -153,37 +151,16 @@
 	@Override
 	public Node getUncommited()
 	{
-		return m_uncommitted;
+		return m_local;
 	}
 
 	@Override
 	public boolean update()
 	{
-		discard();
-		m_tip = m_repository.get();
-		m_uncommitted = m_tip;
-		return true; // !?!?
-	}
-
-	private class Pair<L,R>
-	{
-		private L m_left;
-		private R m_right;
+		m_remote = (SimpleNode)m_browser.useContents();
+		m_local = m_browser.createNode();
 		
-		public Pair(L _left,R _right)
-		{
-			m_left = _left;
-			m_right = _right;
-		}
-		
-		public L getLeft()
-		{
-			return m_left;
-		}
-		
-		public R getRight()
-		{
-			return m_right;
-		}
+		copyNode(m_remote,m_local);
+		return true;
 	}
 }
--- a/src/treecms/proto/simple/SimpleNode.java	Wed Dec 29 03:13:18 2010 +0900
+++ b/src/treecms/proto/simple/SimpleNode.java	Thu Dec 30 00:50:47 2010 +0900
@@ -80,7 +80,7 @@
 	@Override
 	public void addChildren(List<Node> _children)
 	{
-		if(m_children.containsAll(_children)){
+		if(!m_children.containsAll(_children)){
 			m_children.addAll(_children);
 		}
 	}
--- a/src/treecms/proto/simple/test/SimpleEditorTest1.java	Wed Dec 29 03:13:18 2010 +0900
+++ b/src/treecms/proto/simple/test/SimpleEditorTest1.java	Thu Dec 30 00:50:47 2010 +0900
@@ -1,74 +1,22 @@
 /**
  * SimpleEditorTest1
  * 
- * testClone
- *  test monotonic-tree modification
  */
 package treecms.proto.simple.test;
 
-import org.junit.Test;
-import java.util.concurrent.atomic.AtomicReference;
 import org.junit.runner.JUnitCore;
-import treecms.proto.api.*;
 import treecms.proto.simple.*;
+import treecms.proto.test.EditorTest;
 
-public class SimpleEditorTest1
+public class SimpleEditorTest1 extends EditorTest
 {
 	public static void main(String _args[])
 	{
 		JUnitCore.main(SimpleEditorTest1.class.getName());
 	}
-	
-	private AtomicReference<Node> m_root;
-	private Node m_target1;
-	private Node m_target2;
-	
+
 	public SimpleEditorTest1()
 	{
-		//create tree
-		Node root = new SimpleNode();
-		root.setTitle("root");
-		
-		Node child1 = root.addChild(new SimpleNode());
-		child1.setTitle("child1");
-		Node child2 = root.addChild(new SimpleNode());
-		child2.setTitle("child2");
-		
-		Node child11 = child1.addChild(new SimpleNode());
-		child11.setTitle("child11");
-		Node child12 = child1.addChild(new SimpleNode());
-		child12.setTitle("child12");
-		
-		//AtomicReference<T> to use CompareAndSet
-		m_root = new AtomicReference<Node>(root);
-		
-		m_target1 = child2;
-		m_target2 = child11;
-	}
-	
-	@Test
-	public void testClone()
-	{
-		SimpleEditor editor = new SimpleEditor(m_root);
-		Node node = editor.edit(m_target1);
-		node.setTitle("*"+node.getTitle());
-		System.out.println("-----------------------------------------------");
-		print(editor.getUncommited(),0);
-		
-		node = editor.edit(m_target2);
-		node.setTitle("*"+node.getTitle());
-		System.out.println("-----------------------------------------------");
-		print(editor.getUncommited(),0);
-	}
-	
-	private void print(Node _root,int _indent)
-	{
-		for(int i = 0;i < _indent;i ++){
-			System.out.print("\t");
-		}
-		System.out.println(_root.getTitle()+"["+_root.getID()+"]");
-		for(Node child : _root.getChildren()){
-			print(child,_indent+1);
-		}
+		super(new SimpleEditor());
 	}
 }
--- a/src/treecms/proto/simple/test/SimpleEditorTest2.java	Wed Dec 29 03:13:18 2010 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-package treecms.proto.simple.test;
-
-/**
- * SimpleEditorTest2
- * 
- * testMultiThread
- *  test concurrent monotonic-tree modification 
- */
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.junit.Test;
-
-import treecms.proto.api.Node;
-import treecms.proto.simple.SimpleEditor;
-import treecms.proto.simple.SimpleNode;
-import treecms.proto.util.PreOrderTreeWalker;
-
-public class SimpleEditorTest2
-{
-	public static void main(String _args[])
-	{
-		new SimpleEditorTest2();
-	}
-	
-	private AtomicReference<Node> m_contents;
-	
-	public SimpleEditorTest2()
-	{
-		Node root = new SimpleNode();
-		root.setTitle("root");
-		Node c1 = root.addChild(new SimpleNode());
-		c1.setTitle("c1");
-		Node c2 = root.addChild(new SimpleNode());
-		c2.setTitle("c2");
-		
-		
-		Node c11 = c1.addChild(new SimpleNode());
-		c11.setTitle("c11");
-		Node c12 = c1.addChild(new SimpleNode());
-		c12.setTitle("c12");
-		
-		Node c121 = c12.addChild(new SimpleNode());
-		c121.setTitle("c121");
-		
-		m_contents = new AtomicReference<Node>(root);
-		
-		testMultiThread();
-	}
-	
-	@Test
-	public void testMultiThread()
-	{
-		int threads = 10; //number of threads.
-		final int modifyCount = 100;
-		ExecutorService service = Executors.newFixedThreadPool(threads);
-		
-		for(int i = 0;i < threads;i ++){
-			service.execute(new Runnable(){
-
-				@Override
-				public void run()
-				{
-					SimpleEditor editor = new SimpleEditor(m_contents);
-					Random random = new Random();
-					
-					for(int i = 0;i < modifyCount;i ++){
-						List<Node> nodeList = transform(new PreOrderTreeWalker(m_contents.get()));
-						
-						//get random target from nodelist
-						Node target = nodeList.get(Math.abs(random.nextInt(nodeList.size())));
-						
-						//edit target
-						editor.edit(target);
-						
-						//force commit.
-						editor.commit(true);
-					}
-				}
-				
-				/*
-				 * convert iterator to list
-				 */
-				public List<Node> transform(PreOrderTreeWalker _walker)
-				{
-					LinkedList<Node> nodeList = new LinkedList<Node>();
-					for(Node node : _walker){
-						nodeList.add(node);
-					}
-					return nodeList;
-				}
-			});
-		}
-		
-		service.shutdown();
-		
-		try {
-			service.awaitTermination(Long.MAX_VALUE,TimeUnit.DAYS);
-		} catch (InterruptedException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-		
-		print(m_contents.get(),0);
-	}
-		
-	private void print(Node _root,int _indent)
-	{
-		for(int i = 0;i < _indent;i ++){
-			System.out.print("\t");
-		}
-		System.out.println(_root.getTitle()+"["+_root.getID()+"]");
-		for(Node child : _root.getChildren()){
-			print(child,_indent+1);
-		}
-	}
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/treecms/proto/test/EditorTest.java	Thu Dec 30 00:50:47 2010 +0900
@@ -0,0 +1,85 @@
+package treecms.proto.test;
+
+import java.util.LinkedList;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import treecms.proto.api.*;
+import treecms.proto.util.PreOrderTreeWalker;
+
+public class EditorTest
+{
+	private Editor m_editor;
+	private Node m_root,m_child1,m_child11,m_child12,m_child2;
+	
+	public EditorTest(Editor _editor)
+	{
+		m_editor = _editor;
+		m_root = _editor.useContents();
+		
+		//create tree
+		m_root.setTitle("root");
+		
+		m_child1 = m_root.addChild(m_root.createNode());
+		m_child1.setTitle("child1");
+		m_child2 = m_root.addChild(m_root.createNode());
+		m_child2.setTitle("child2");
+		
+		m_child11 = m_child1.addChild(m_root.createNode());
+		m_child11.setTitle("child11");
+		m_child12 = m_child1.addChild(m_root.createNode());
+		m_child12.setTitle("child12");
+	}
+	
+	@Test
+	public void testClone()
+	{
+		Node target = m_editor.edit(m_child11);
+		Assert.assertEquals(true,target.getID().isOrderThen(m_child11.getID()));
+	}
+	
+	public LinkedList<Node> findPath(Node _root,Node _target)
+	{
+		LinkedList<Node> path = new LinkedList<Node>();
+		
+		if(findPath(_root,_target,path)){
+			path.addFirst(_root);
+		}
+		
+		return path;
+	}
+	
+	private boolean findPath(Node _parent,Node _target,LinkedList<Node> _path)
+	{
+		if(_target.getID().isFamily(_parent.getID())){
+			return true;
+		}
+		
+		for(Node child : _parent.getChildren()){
+			if(findPath(child,_target,_path)){
+				_path.addFirst(child);
+				return true;
+			}
+		}
+		
+		return false;
+	}
+	
+	public void print(Node _root)
+	{
+		print(_root,0);
+	}
+	
+	private void print(Node _root,int _indent)
+	{
+		for(int i = 0;i < _indent;i ++){
+			System.out.print("\t");
+		}
+		System.out.println(_root.getTitle()+"["+_root.getID()+"]");
+		for(Node child : _root.getChildren()){
+			print(child,_indent+1);
+		}
+	}
+}
--- a/src/treecms/proto/test/NodeTest.java	Wed Dec 29 03:13:18 2010 +0900
+++ b/src/treecms/proto/test/NodeTest.java	Thu Dec 30 00:50:47 2010 +0900
@@ -138,4 +138,28 @@
 		Assert.assertEquals(children.get(1),node);
 		Assert.assertEquals(children.get(2),child3);
 	}
+	
+	@Test
+	public void testChildrenOperation()
+	{
+		m_node.addChild(m_node.createNode());
+		m_node.addChild(m_node.createNode());
+		m_node.addChild(m_node.createNode());
+		
+		Assert.assertEquals(3,m_node.getChildren().size());
+		
+		Node node = m_node.createNode();
+		node.addChildren(m_node.getChildren());
+		Assert.assertEquals(3,node.getChildren().size());
+	}
+	
+	@Test
+	public void testAttributeOperation()
+	{
+		String key = "test";
+		String value = "value";
+		m_node.setAttribute(key,value);
+		
+		Assert.assertEquals(true,value.equals(m_node.getAttribute(key)));
+	}
 }
--- a/src/treecms/proto/util/RandomSimpleTreeBuilder.java	Wed Dec 29 03:13:18 2010 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-package treecms.proto.util;
-
-import java.util.Random;
-
-import treecms.proto.api.Node;
-import treecms.proto.simple.SimpleNode;
-
-public class RandomSimpleTreeBuilder
-{
-	public static void main(String _args[])
-	{
-		SimpleNode root = RandomSimpleTreeBuilder.randomTree(2,2,3,3);
-		print(0,root);
-	}
-	
-	public static void print(int _indent,Node _parent)
-	{
-		for(int i = 0;i < _indent;i ++){
-			System.out.print("\t");
-		}
-		System.out.println(_parent.getTitle());
-		
-		for(Node child : _parent.getChildren()){
-			print(_indent + 1,child);
-		}
-	}
-	
-	public static SimpleNode randomTree(int _maxRow,int _maxCol)
-	{
-		return randomTree(0,0,_maxRow,_maxCol);
-	}
-	
-	public static SimpleNode randomTree(int _minRow,int _minCol,int _maxRow,int _maxCol)
-	{
-		RandomSimpleTreeBuilder builder = new RandomSimpleTreeBuilder(_minRow,_minCol,_maxRow,_maxCol);
-		return builder.generate();
-	}
-	
-	private int m_minCol;
-	private int m_maxRow,m_maxCol;
-	
-	private RandomSimpleTreeBuilder(int _minRow,int _minCol,int _maxRow,int _maxCol)
-	{
-		m_minCol = _minCol;
-		m_maxRow = _maxRow;
-		m_maxCol = _maxCol;
-	}
-	
-	public SimpleNode generate()
-	{
-		SimpleNode root = new SimpleNode();
-		root.setTitle("root");
-		
-		Random rand = new Random();
-		int childs = m_minCol + rand.nextInt(m_maxCol)*(1 - m_minCol/(1 + m_maxCol));
-		for(int i = 1;i < childs;i ++){
-			SimpleNode child = (SimpleNode)root.addChild(new SimpleNode());
-			child.setTitle("c"+i);
-			generate(child,1,rand);
-		}
-		return root;
-	}
-	
-	private void generate(SimpleNode _parent,int _row,Random _rand)
-	{
-		if(_row >= m_maxRow || _rand.nextInt(m_maxRow) == 0){
-			return;
-		}
-		
-		int childs = m_minCol + _rand.nextInt(m_maxCol)*(1 - m_minCol/(1 + m_maxCol));
-		for(int i = 1;i < childs;i ++){
-			SimpleNode child = (SimpleNode)_parent.addChild(new SimpleNode());
-			child.setTitle(_parent.getTitle()+i);
-			generate(child,_row + 1,_rand);
-		}
-	}
-	
-}