# HG changeset patch # User suika6039 # Date 1293637847 -32400 # Node ID e647bb37b7adc7f4e35be5549bdc0774eb5f487c # Parent 78e9b96ef04aadb7182dd96f583dd5588a042b4e added treecms.proto.merge diff -r 78e9b96ef04a -r e647bb37b7ad src/treecms/proto/api/Editor.java --- 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(); } diff -r 78e9b96ef04a -r e647bb37b7ad src/treecms/proto/gui/GraphicalMonotonicTreeEditor.java --- 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 repo = new AtomicReference(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); diff -r 78e9b96ef04a -r e647bb37b7ad src/treecms/proto/marge/Marger.java --- /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); +} diff -r 78e9b96ef04a -r e647bb37b7ad src/treecms/proto/marge/ReplaceMarger.java --- /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; + } + +} diff -r 78e9b96ef04a -r e647bb37b7ad src/treecms/proto/simple/SimpleEditor.java --- 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 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> m_editLog; // there is noting for it but to do. + public SimpleEditor() + { + update(); + } - public SimpleEditor(AtomicReference _contents) + public void copyNode(Node _from,Node _to) { - m_repository = _contents; - m_tip = m_repository.get(); - m_uncommitted = m_tip; - m_editLog = new LinkedList>(); + _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> log = new LinkedList>(m_editLog); //backup - - update(); - for(Pair 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 path = findPath(m_uncommitted,_target); + LinkedList path = findPath(m_local,_target); if(path.isEmpty()){ return null; } LinkedList change = new LinkedList(); - 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(_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 _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 - { - 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; } } diff -r 78e9b96ef04a -r e647bb37b7ad src/treecms/proto/simple/SimpleNode.java --- 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 _children) { - if(m_children.containsAll(_children)){ + if(!m_children.containsAll(_children)){ m_children.addAll(_children); } } diff -r 78e9b96ef04a -r e647bb37b7ad src/treecms/proto/simple/test/SimpleEditorTest1.java --- 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 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 to use CompareAndSet - m_root = new AtomicReference(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()); } } diff -r 78e9b96ef04a -r e647bb37b7ad src/treecms/proto/simple/test/SimpleEditorTest2.java --- 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 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(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 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 transform(PreOrderTreeWalker _walker) - { - LinkedList nodeList = new LinkedList(); - 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); - } - } -} diff -r 78e9b96ef04a -r e647bb37b7ad src/treecms/proto/test/EditorTest.java --- /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 findPath(Node _root,Node _target) + { + LinkedList path = new LinkedList(); + + if(findPath(_root,_target,path)){ + path.addFirst(_root); + } + + return path; + } + + private boolean findPath(Node _parent,Node _target,LinkedList _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); + } + } +} diff -r 78e9b96ef04a -r e647bb37b7ad src/treecms/proto/test/NodeTest.java --- 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))); + } } diff -r 78e9b96ef04a -r e647bb37b7ad src/treecms/proto/util/RandomSimpleTreeBuilder.java --- 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); - } - } - -}