changeset 279:86d44dd80b1c

add DifferenceListTree test fix
author tatsuki
date Mon, 19 Dec 2016 22:10:14 +0900
parents f69b2a5a821d
children 9f38fcb07d36
files src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/DefaultJungle.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/TreeContext.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/logger/DefaultOperationLog.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/logger/OperationLog.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/DefaultTreeContext.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/DifferenceTreeContext.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/editor/jungleTreeEditor/DifferenceJungleTreeEditor.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DefaultTransactionManager.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DifferenceTransactionManager.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/TransactionManager.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/tree/DifferenceListJungleTree.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/util/Error/TreeEditorError.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentTransactionManager.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentTreeContext.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transaction/NetworkTransactionManager.java src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/core/treeeditor/Difference/DifferencialJungleTreeEditorTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/core/treeeditor/Difference/MultiDifferencialJngleTreeEditorTest.java
diffstat 17 files changed, 193 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/DefaultJungle.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/DefaultJungle.java	Mon Dec 19 22:10:14 2016 +0900
@@ -19,7 +19,6 @@
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.Default.DefaultTreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.Differencial.DifferencialTreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNodeChildren;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.DefaultTraverser;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.Traverser;
@@ -116,13 +115,6 @@
 
     @Override
     public JungleTree createNewDifferenceTree(final String name, TreeNode rootNode) {
-        TreeNode unDefineNode = new DifferencialTreeNode();
-        TreeNodeChildren children = rootNode.getChildren();
-        Either<Error, TreeNode> either = children.addNewChildAt(0, unDefineNode);
-        if (either.isA()) {
-            return null;
-        }
-        TreeNode newRootNode = either.b();
         ChangeList list = new ChangeList() {
             @Override
             public Iterator<TreeOperation> iterator() {
@@ -146,8 +138,8 @@
             }
 
         };
-        InterfaceTraverser traverser = new InterfaceTraverser(newRootNode, true);
-        TreeContext tc = new DifferenceTreeContext(newRootNode, unDefineNode,null ,list, uuid, name, 0, traverser);
+        InterfaceTraverser traverser = new InterfaceTraverser(rootNode, true);
+        TreeContext tc = new DifferenceTreeContext(rootNode, rootNode,null ,list, uuid, name, 0, traverser);
         JungleTree newTree = new DifferenceListJungleTree(tc, uuid, journal.getWriter(), differenceEditor);
         if (trees.putIfAbsent(name, newTree) != null) {
             return null;
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/TreeContext.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/TreeContext.java	Mon Dec 19 22:10:14 2016 +0900
@@ -12,7 +12,9 @@
 public interface TreeContext {
     public TreeNode getRoot();
 
-    public TreeNode getUnDefineNode();
+    public TreeNode getAppendedNode();
+
+    public boolean setAppendedNode(TreeNode AppendedNode);
 
     public TreeContext prev();
 
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/logger/DefaultOperationLog.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/logger/DefaultOperationLog.java	Mon Dec 19 22:10:14 2016 +0900
@@ -9,20 +9,23 @@
 public class DefaultOperationLog implements OperationLog
 {
 	private final List<NodeOperation> log;
-	
+	private final NodeOperation lastLog;
+
 	private static final List<NodeOperation> EMPTY =new List<>();
 	
 	public DefaultOperationLog()
 	{
-		this(EMPTY);
+		this(EMPTY,null);
 	}
 
 	public DefaultOperationLog(NodeOperation op) {
-		log = EMPTY.addLast(op);
+		this.log = EMPTY.addLast(op);
+		this.lastLog = op;
 	}
-	private DefaultOperationLog(List<NodeOperation> _log)
-	{
-		log = _log;
+
+	private DefaultOperationLog(List<NodeOperation> _log , NodeOperation lastLog) {
+		this.log = _log;
+		this.lastLog = lastLog;
 	}
 
 	@Override
@@ -33,9 +36,9 @@
 
 
 	@Override
-	public DefaultOperationLog add(NodeOperation _op)
+	public DefaultOperationLog add(NodeOperation op)
 	{
-		return new DefaultOperationLog(log.addLast(_op));
+		return new DefaultOperationLog(log.addLast(op),op);
 	}
 
 	@Override
@@ -43,4 +46,9 @@
 	{
 		return log.length();
 	}
+
+	@Override
+	public NodeOperation getLastLog() {
+		return lastLog;
+	}
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/logger/OperationLog.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/logger/OperationLog.java	Mon Dec 19 22:10:14 2016 +0900
@@ -7,4 +7,5 @@
 {
 	public OperationLog add(NodeOperation _op);
 	public int length();
+	public NodeOperation getLastLog();
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/DefaultTreeContext.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/DefaultTreeContext.java	Mon Dec 19 22:10:14 2016 +0900
@@ -36,11 +36,16 @@
     }
 
     @Override
-    public TreeNode getUnDefineNode(){
+    public TreeNode getAppendedNode(){
         return null; // not use
     }
 
     @Override
+    public boolean setAppendedNode(TreeNode AppendedNode) {
+        return false; // 使わない
+    }
+
+    @Override
     public TreeContext prev() {
         return previous;
     }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/DifferenceTreeContext.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/DifferenceTreeContext.java	Mon Dec 19 22:10:14 2016 +0900
@@ -9,12 +9,10 @@
 import jp.ac.u_ryukyu.ie.cr.jungle.store.operations.TreeOperation;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
 
-/**
- * Created by e115731 on 2016/12/13.
- */
+
 public class DifferenceTreeContext implements TreeContext {
     private final TreeNode root;
-    private final TreeNode unDefineNode;
+    private TreeNode appendedNode;
     private final TreeContext previous;
     private final ChangeList changeList;
     private final String uuid;
@@ -23,9 +21,9 @@
     private final InterfaceTraverser traverser;
 
 
-    public DifferenceTreeContext(TreeNode root, TreeNode unDefineNode, TreeContext _prev, ChangeList _log, String _uuid, String _treeName, long _revision, InterfaceTraverser traverser) {
+    public DifferenceTreeContext(TreeNode root, TreeNode appendedNode, TreeContext _prev, ChangeList _log, String _uuid, String _treeName, long _revision, InterfaceTraverser traverser) {
         this.root = root;
-        this.unDefineNode = unDefineNode;
+        this.appendedNode = appendedNode;
         this.previous = _prev;
         this.changeList = _log;
         this.uuid = _uuid;
@@ -41,8 +39,16 @@
     }
 
     @Override
-    public TreeNode getUnDefineNode(){
-        return unDefineNode;
+    public TreeNode getAppendedNode(){
+        return appendedNode;
+    }
+
+    @Override
+    public boolean setAppendedNode(TreeNode appendedNode) {
+        if (this.appendedNode != null)
+            return false;
+        this.appendedNode = appendedNode;
+        return true;
     }
 
     @Override
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/editor/jungleTreeEditor/DifferenceJungleTreeEditor.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/editor/jungleTreeEditor/DifferenceJungleTreeEditor.java	Mon Dec 19 22:10:14 2016 +0900
@@ -21,6 +21,10 @@
 
 import java.nio.ByteBuffer;
 
+import static jp.ac.u_ryukyu.ie.cr.jungle.store.Command.APPEND_CHILD;
+import static jp.ac.u_ryukyu.ie.cr.jungle.util.Error.TreeEditorError.ADD_NEW_CHILD_ERROR;
+import static jp.ac.u_ryukyu.ie.cr.jungle.util.Error.TreeEditorError.SET_APPENDEDNODE_ERROR;
+
 
 public class DifferenceJungleTreeEditor implements JungleTreeEditor {
 
@@ -28,17 +32,19 @@
     private final TreeEditor editor;
     private final TreeOperationLog log;
     private final TreeNode subTreeRoot;
+    private TreeNode appendedNode;
 
     public DifferenceJungleTreeEditor(TreeNode subTreeRoot, TransactionManager txManager, TreeEditor editor) {
-        this(subTreeRoot, txManager, editor, new DefaultTreeOperationLog());
+        this(subTreeRoot, subTreeRoot, txManager, editor, new DefaultTreeOperationLog());
     }
 
 
-    public DifferenceJungleTreeEditor(TreeNode subTreeRoot, TransactionManager txManager, TreeEditor editor, TreeOperationLog log) {
+    public DifferenceJungleTreeEditor(TreeNode subTreeRoot, TreeNode appendedNode, TransactionManager txManager, TreeEditor editor, TreeOperationLog log) {
         this.txManager = txManager;
         this.editor = editor;
         this.log = log;
         this.subTreeRoot = subTreeRoot;
+        this.appendedNode = appendedNode;
     }
 
     private Either<Error, JungleTreeEditor> _edit(final NodePath _path, NodeEditor _e) {
@@ -50,8 +56,7 @@
 
         LoggingNode newLogging = editEither.b();
         OperationLog newLog = newLogging.getOperationLog();
-        TreeNode newNode = newLogging.getWrap();
-
+        NodeOperation op = newLog.getLastLog();
         IterableConverter.Converter<TreeOperation, NodeOperation> converter = new IterableConverter.Converter<TreeOperation, NodeOperation>() {
             @Override
             public TreeOperation conv(NodeOperation _b) {
@@ -63,7 +68,18 @@
         DefaultTreeOperationLog treeOperationLog = new DefaultTreeOperationLog(iterable, newLog.length());
         TreeOperationLog newTreeOpLog = log.append(treeOperationLog);
 
-        JungleTreeEditor newEditor = new DifferenceJungleTreeEditor(subTreeRoot, txManager, editor, newTreeOpLog);
+        JungleTreeEditor newEditor;
+
+        if (op.getCommand() == APPEND_CHILD) {
+            TreeNode newNode = newLogging.getWrap();
+            int position = op.getPosition();
+            Either<Error,TreeNode> either = newNode.getChildren().at(position);
+            if (either.isA())
+                return DefaultEither.newA(ADD_NEW_CHILD_ERROR);
+            TreeNode newChild = either.b();
+            newEditor = new DifferenceJungleTreeEditor(subTreeRoot, newChild, txManager, editor, newTreeOpLog);
+        } else
+            newEditor = new DifferenceJungleTreeEditor(subTreeRoot, appendedNode, txManager, editor, newTreeOpLog);
         return DefaultEither.newB(newEditor);
     }
 
@@ -116,10 +132,10 @@
         if (either.isA()) {
             return DefaultEither.newA(either.a());
         }
-
         TransactionManager newTxManager = either.b();
+        if (!newTxManager.setAppendedNode(appendedNode))
+            return DefaultEither.newA(SET_APPENDEDNODE_ERROR);
         JungleTreeEditor newTreeEditor = new DifferenceJungleTreeEditor(new DifferencialTreeNode(), newTxManager, editor);
-
         return DefaultEither.newB(newTreeEditor);
     }
 
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DefaultTransactionManager.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DefaultTransactionManager.java	Mon Dec 19 22:10:14 2016 +0900
@@ -78,6 +78,11 @@
     }
 
     @Override
+    public boolean setAppendedNode(TreeNode appendedNode) {
+        return false; //使わない
+    }
+
+    @Override
     public String getUUID() {
         return uuid;
     }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DifferenceTransactionManager.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DifferenceTransactionManager.java	Mon Dec 19 22:10:14 2016 +0900
@@ -3,14 +3,12 @@
 import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeList;
 import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeListWriter;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.TreeContext;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.TreeOperationLog;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.operations.Commit;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.operations.NodeOperation;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.operations.TreeOperation;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.DifferenceTreeContext;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.Differencial.DifferencialTreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNodeChildren;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
@@ -19,10 +17,10 @@
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
 
 import java.util.Iterator;
-import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReference;
 
-import static jp.ac.u_ryukyu.ie.cr.jungle.util.Error.TreeEditorError.*;
+import static jp.ac.u_ryukyu.ie.cr.jungle.util.Error.TreeEditorError.APPENDED_NODE_NULL;
+import static jp.ac.u_ryukyu.ie.cr.jungle.util.Error.TreeEditorError.CAS_MISS;
 
 public class DifferenceTransactionManager implements TransactionManager {
     private final AtomicReference<TreeContext> repository;
@@ -64,21 +62,18 @@
             @Override
             public String uuid() {
                 return uuid;
+
             }
-
         };
 
-        TreeNode newUnDefineNode = new DifferencialTreeNode();
-        Either<Error, TreeNode> either = createSubTreeUnDefineNode(subTreeRoot, newUnDefineNode);
-        if (either.isA())
-            return DefaultEither.newA(ADD_NEW_CHILD_ERROR);
         TreeNode root = tip.getRoot();
         InterfaceTraverser traverser = new InterfaceTraverser(root, true);
-        traverser.createIndex();
-        TreeContext newTreeContext = new DifferenceTreeContext(root, newUnDefineNode, tip, list, uuid, _treeName, nextRevision, traverser);
-
+        TreeContext newTreeContext = new DifferenceTreeContext(root, null, tip, list, uuid, _treeName, nextRevision, traverser);
+        if (tip.getAppendedNode() == null)
+            return DefaultEither.newA(APPENDED_NODE_NULL);
         if (repository.compareAndSet(newTreeContext.prev(), newTreeContext)) {
-            either = replaceUnDefineNode(subTreeRoot);
+            traverser.createIndex();
+            Either<Error, TreeNode> either = replaceUnDefineNode(subTreeRoot);
             if (either.isA())
                 return DefaultEither.newA(either.a());
             TransactionManager txManager = new DifferenceTransactionManager(writer, newTreeContext, repository, uuid);
@@ -89,27 +84,11 @@
     }
 
     private Either<Error, TreeNode> replaceUnDefineNode(TreeNode subTreeRoot) {
-        TreeNode unDefineNode = tip.getUnDefineNode();
-        ParentIndex parentIndex = tip.getParentIndex();
-        Optional<TreeNode> parentOfUndefineNodeOptional = parentIndex.get(unDefineNode);
-        if (!parentOfUndefineNodeOptional.isPresent())
-            return DefaultEither.newA(UNDEFINENODE_PARENT_NOT_FOUND);
-        TreeNode parentOfUndefineNode = parentOfUndefineNodeOptional.get();
-        TreeNodeChildren children = parentOfUndefineNode.getChildren();
-        return children.replaceNode(0, subTreeRoot);
+        TreeNode appendedNode = tip.getAppendedNode();
+        TreeNodeChildren children = appendedNode.getChildren();
+        return children.addNewChildAt(0, subTreeRoot);
     }
 
-    private Either<Error, TreeNode> createSubTreeUnDefineNode(TreeNode subTreeRoot, TreeNode newUnDefineNode) {
-        TreeNode n = subTreeRoot;
-        while (true) {
-            TreeNodeChildren children = n.getChildren();
-            Either<Error, TreeNode> either = children.at(0);
-            if (either.isA())
-                break;
-            n = either.b();
-        }
-        return n.getChildren().addNewChildAt(0, newUnDefineNode);
-    }
 
     @Override
     public Either<Error, TransactionManager> flashCommit(TreeNode _newRoot, TreeOperationLog _log) {
@@ -117,6 +96,11 @@
     }
 
     @Override
+    public boolean setAppendedNode(TreeNode appendedNode) {
+        return tip.setAppendedNode(appendedNode);
+    }
+
+    @Override
     public String getUUID() {
         return uuid;
     }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/TransactionManager.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/TransactionManager.java	Mon Dec 19 22:10:14 2016 +0900
@@ -10,6 +10,7 @@
 {
 	public Either<Error,TransactionManager> commit(TreeNode _newRoot,TreeOperationLog _log);
     public Either<Error,TransactionManager> flashCommit(TreeNode _newRoot,TreeOperationLog _log);
+	public boolean setAppendedNode(TreeNode appendedNode);
 	public String getUUID();
 	public long getRevision();
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/tree/DifferenceListJungleTree.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/tree/DifferenceListJungleTree.java	Mon Dec 19 22:10:14 2016 +0900
@@ -8,6 +8,7 @@
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.treeEditor.TreeEditor;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.manager.DifferenceTransactionManager;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.manager.TransactionManager;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.Differencial.DifferencialTreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 
 import java.util.concurrent.atomic.AtomicReference;
@@ -25,8 +26,8 @@
         String uuid = super.getUuid();
         TreeEditor treeEditor = super.getTreeEditor();
         TransactionManager txManager = new DifferenceTransactionManager(writer, tc, repository, uuid);
-        TreeNode root = tc.getRoot();
-        return new DifferenceJungleTreeEditor(root, txManager, treeEditor);
+        TreeNode subTreeRoot = new DifferencialTreeNode();
+        return new DifferenceJungleTreeEditor(subTreeRoot, txManager, treeEditor);
     }
 
 
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/util/Error/TreeEditorError.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/util/Error/TreeEditorError.java	Mon Dec 19 22:10:14 2016 +0900
@@ -7,5 +7,7 @@
 	public static final Error ADD_NEW_CHILD_ERROR = new DefaultError();
 	public static final Error UNDEFINENODE_PARENT_NOT_FOUND = new DefaultError();
 	public static final Error CAS_MISS = new DefaultError();
+	public static final Error APPENDED_NODE_NULL = new DefaultError();
+	public static final Error SET_APPENDEDNODE_ERROR= new DefaultError();
 
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentTransactionManager.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentTransactionManager.java	Mon Dec 19 22:10:14 2016 +0900
@@ -82,6 +82,11 @@
     }
 
     @Override
+    public boolean setAppendedNode(TreeNode appendedNode) {
+        return false; // 使わない
+    }
+
+    @Override
     public long getRevision() {
         return tip.revision();
     }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentTreeContext.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentTreeContext.java	Mon Dec 19 22:10:14 2016 +0900
@@ -36,11 +36,16 @@
     }
 
     @Override
-    public TreeNode getUnDefineNode() {
+    public TreeNode getAppendedNode() {
         return null; // not use
     }
 
     @Override
+    public boolean setAppendedNode(TreeNode AppendedNode) {
+        return false; //使わない
+    }
+
+    @Override
     public TreeContext prev() {
         return previous;
     }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transaction/NetworkTransactionManager.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transaction/NetworkTransactionManager.java	Mon Dec 19 22:10:14 2016 +0900
@@ -80,6 +80,11 @@
     }
 
     @Override
+    public boolean setAppendedNode(TreeNode appendedNode) {
+        return false; //使わない
+    }
+
+    @Override
     public long getRevision() {
         return tip.revision();
     }
--- a/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/core/treeeditor/Difference/DifferencialJungleTreeEditorTest.java	Mon Dec 19 02:15:23 2016 +0900
+++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/core/treeeditor/Difference/DifferencialJungleTreeEditorTest.java	Mon Dec 19 22:10:14 2016 +0900
@@ -5,6 +5,9 @@
 import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.NodePath;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNodeAttributes;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNodeChildren;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.DefaultTraverser;
 import jp.ac.u_ryukyu.ie.cr.jungle.tree.JungleTree;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
@@ -24,16 +27,34 @@
         JungleTree tree = jungle.createNewDifferenceTree("df");
         JungleTreeEditor editor = tree.getJungleTreeEditor();
         NodePath path = new DefaultNodePath();
-        Either<Error, JungleTreeEditor> addNewChildEither = editor.addNewChildAt(path, 0);
-        Assert.assertFalse(addNewChildEither.isA());
-        JungleTreeEditor childAddedTreeEditor = addNewChildEither.b();
+        Either<Error, JungleTreeEditor> either = editor.addNewChildAt(path, 0);
+        Assert.assertFalse(either.isA());
+        JungleTreeEditor editor2 = either.b();
+        Either<Error, JungleTreeEditor> either2 = editor2.addNewChildAt(path, 0);
+        Assert.assertFalse(either2.isA());
+        JungleTreeEditor editor3 = either2.b();
         NodePath putAttributeNodePath = path.add(0);
-        Either<Error, JungleTreeEditor>  putAttributedEither= childAddedTreeEditor.putAttribute(putAttributeNodePath,"key", ByteBuffer.wrap("value".getBytes()));
-        Assert.assertFalse(putAttributedEither.isA());
-        JungleTreeEditor putAttributedTreeEditor = putAttributedEither.b();
-        Either<Error, JungleTreeEditor> commitedEither = putAttributedTreeEditor.success();
-        Assert.assertFalse(commitedEither.isA());
-        JungleTreeEditor commitedTreeEditor = commitedEither.b();
-        System.out.println("test");
+        Either<Error, JungleTreeEditor>  either3= editor3.putAttribute(putAttributeNodePath,"key", ByteBuffer.wrap("value".getBytes()));
+        Assert.assertFalse(either3.isA());
+        JungleTreeEditor editor4 = either3.b();
+        Either<Error, JungleTreeEditor> either4 = editor4.success();
+        Assert.assertFalse(either4.isA());
+        TreeNode root = tree.getRootNode();
+        TreeNodeChildren children = root.getChildren();
+        int expectChildCount = 1;
+        Assert.assertEquals(expectChildCount,children.size());
+        Either<Error,TreeNode> either5 = children.at(0);
+        Assert.assertFalse(either5.isA());
+        TreeNode child = either5.b();
+        TreeNodeChildren children2 = child.getChildren();
+        expectChildCount = 2;
+        Assert.assertEquals(expectChildCount,children2.size());
+        Either<Error,TreeNode> either6 = children2.at(0);
+        Assert.assertFalse(either6.isA());
+        TreeNode child2 = either6.b();
+        TreeNodeAttributes attribute = child2.getAttributes();
+        String expectValue = "value";
+        String value = attribute.getString("key");
+        Assert.assertEquals(value,expectValue);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/core/treeeditor/Difference/MultiDifferencialJngleTreeEditorTest.java	Mon Dec 19 22:10:14 2016 +0900
@@ -0,0 +1,54 @@
+package jp.ac.u_ryukyu.ie.cr.jungle.core.treeeditor.Difference;
+
+import jp.ac.u_ryukyu.ie.cr.jungle.DefaultJungle;
+import jp.ac.u_ryukyu.ie.cr.jungle.Jungle;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.NodePath;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor;
+import jp.ac.u_ryukyu.ie.cr.jungle.traverser.DefaultTraverser;
+import jp.ac.u_ryukyu.ie.cr.jungle.tree.JungleTree;
+import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
+import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * デバッガで確かめる
+ */
+public class MultiDifferencialJngleTreeEditorTest {
+    @Test
+    public void MultiDifferencialJngleTreeEditorTests() throws InterruptedException {
+        Jungle jungle = new DefaultJungle(null, "hogehoge", new DefaultTraverser());
+        JungleTree tree = jungle.createNewDifferenceTree("df");
+        Thread t1 = new EditorThread(tree);
+        Thread t2 = new EditorThread(tree);
+        t1.start();
+        t2.start();
+        System.out.println("start");
+        t1.join();
+        t2.join();
+
+    }
+
+    private class EditorThread extends Thread {
+        JungleTree tree;
+        EditorThread(JungleTree tree) {
+        this.tree = tree;
+        }
+
+        @Override
+        public void run(){
+            Either<Error, JungleTreeEditor> either2;
+            System.out.println(getName() + "thread");
+            do {
+                JungleTreeEditor editor = tree.getJungleTreeEditor();
+                NodePath path = new DefaultNodePath();
+                Either<Error, JungleTreeEditor> either = editor.addNewChildAt(path, 0);
+                Assert.assertFalse(either.isA());
+                JungleTreeEditor editor2 = either.b();
+                either2 = editor2.success();
+                System.out.println(getName() + "success");
+            } while(either2.isA());
+        }
+    }
+}