changeset 282:5da8a19dbe76

fix index difference update
author tatsuki
date Fri, 30 Dec 2016 03:55:55 +0900
parents 8a746ab2dd02
children 11285c2fbc8b
files src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/core/Attributes.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/DefaultNode.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/List.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/Node.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/TailNode.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/headNode.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/treemap/Node.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/treemap/TreeMap.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/index/Index.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/IndexCreater.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/IndexUpdater.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/ParentIndex.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/logger/LoggingNode.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/AppendChildAt.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/DeleteAttribute.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/DeleteChildAt.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/MoveChild.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/NodeEditor.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/PutAttribute.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/replaceRootNodeAt.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/DefaultJungleTreeEditor.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/editor/treeEditor/DefaultTreeEditor.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/transaction/node/TreeNodeAttributes.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/traverser/InterfaceTraverser.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/tree/DefaultJungleTree.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/tree/JungleTree.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentJungleTree.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentJungleTreeEditor.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/NetworkDefaultJungleTree.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transaction/NetworkDefaultJungleTreeEditor.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transaction/NetworkTransactionManager.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transformer/NetworkAppendChildAt.java src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/CreateTreeMethod.java src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/index/IndexTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/index/ParentIndexPutTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/index/parentIndexTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/traverse/InterfaceTraverserTest.java
diffstat 46 files changed, 826 insertions(+), 462 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/core/Attributes.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/core/Attributes.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,9 +1,14 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.core;
 
 import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.List;
 
 public interface Attributes
 {
 	public ByteBuffer get(String key);
 	public String getString(String key);
+	public Iterator<String> getKeys();
+	public boolean contain(String key);
+	public Iterator<String> getFilteringKey(List<String> filter);
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/DefaultNode.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/DefaultNode.java	Fri Dec 30 03:55:55 2016 +0900
@@ -50,6 +50,20 @@
         return new DefaultNode<>(this.attribute, newNode);
     }
 
+
+    @Override
+    public Node<T> delete(T node) {
+        if (node.equals(this.next.getAttribute())) {
+            return new DefaultNode<>(this.attribute, this.next.getNext());
+        }
+
+        Node<T> newNode = next.delete(node);
+        if (newNode == null)
+            return null;
+
+        return new DefaultNode<>(this.attribute, newNode);
+    }
+
     @Override
     public Node<T> replaceNode(int currentNum, int num, T attribute) {
         if (currentNum == num) {
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/List.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/List.java	Fri Dec 30 03:55:55 2016 +0900
@@ -99,6 +99,12 @@
         return new List<>(newNode);
     }
 
+    public List<T> delete(T node) {
+        Node<T> newNode = head.delete(node);
+        if (newNode == null) return this;
+        return new List<>(newNode);
+    }
+
     public List<T> replace(int num, T attribute) {
         Node<T> newHead = head.replaceNode(0, num, attribute);
         if (newHead == null) return this;
@@ -149,4 +155,5 @@
     }
 
 
+
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/Node.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/Node.java	Fri Dec 30 03:55:55 2016 +0900
@@ -13,7 +13,10 @@
 
     public Node<T> delete(int currentNum, int num);
 
+    Node<T> delete(T node);
+
     public Node<T> replaceNode(int currentNum, int num, T attribute);
 
     public int length();
+
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/TailNode.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/TailNode.java	Fri Dec 30 03:55:55 2016 +0900
@@ -23,6 +23,11 @@
     }
 
     @Override
+    public Node<T> delete(T node) {
+        return null;
+    }
+
+    @Override
     public Node<T> replaceNode(int currentNum, int num, T attribute) {
         return null;
     }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/headNode.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/list/headNode.java	Fri Dec 30 03:55:55 2016 +0900
@@ -48,6 +48,19 @@
     }
 
     @Override
+    public Node<T> delete(T node) {
+        if (node.equals(this.next.getAttribute())) {
+            return new headNode<>(this.next.getNext());
+        }
+
+        Node<T> newNode = next.delete(node);
+        if (newNode == null)
+            return null;
+
+        return new headNode<>(newNode);
+    }
+
+    @Override
     public Node<T> replaceNode(int currentNum, int num, T attribute) {
         Node<T> nextNode = getNext();
         Node<T> newNode = nextNode.replaceNode(currentNum, num, attribute);
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/treemap/Node.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/treemap/Node.java	Fri Dec 30 03:55:55 2016 +0900
@@ -106,7 +106,7 @@
 
             return new rebuildNode<>(false, newParent);
         }
-        return null;
+        return new rebuildNode<>(false,null);
     }
 
     @SuppressWarnings("unchecked")
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/treemap/TreeMap.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/treemap/TreeMap.java	Fri Dec 30 03:55:55 2016 +0900
@@ -32,6 +32,11 @@
         return root;
     }
 
+    public boolean contain(final K key){
+        Optional<V> optional = root.get(key, this.comparator);
+        return optional.isPresent();
+    }
+
     public Optional<V> get(final K key) {
         return root.get(key, this.comparator);
     }
@@ -57,7 +62,7 @@
             return this;
         rebuildNode<K,V> rootRebuildNode = root.delete(key, null, comparator, Rotate.N);
         if (!rootRebuildNode.notEmpty())
-            return this; // not key
+            return this; // 削除するノードが無かった場合
         Node<K,V> root = rootRebuildNode.getNode();
         if (!root.isNotEmpty())
             return new TreeMap<>(new EmptyNode<>(), this.comparator);
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/TreeContext.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/TreeContext.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,13 +1,12 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.store;
 
 
-import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeList;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.Index;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.operations.TreeOperation;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap;
 
 public interface TreeContext {
     public TreeNode getRoot();
@@ -26,7 +25,7 @@
 
     public long revision();
 
-    public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex();
+    public Index getIndex();
 
     public Iterable<TreeOperation> getOperations();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/Index.java	Fri Dec 30 03:55:55 2016 +0900
@@ -0,0 +1,92 @@
+package jp.ac.u_ryukyu.ie.cr.jungle.store.index;
+
+import jp.ac.u_ryukyu.ie.cr.jungle.core.Attributes;
+import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
+import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.NulIterator;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
+
+import java.util.Iterator;
+import java.util.Optional;
+
+
+public class Index {
+    private final TreeMap<String, TreeMap<String, List<TreeNode>>> indexList;
+
+    public Index(){
+        this.indexList = new TreeMap<>();
+    }
+
+    private Index(TreeMap<String, TreeMap<String, List<TreeNode>>> indexList){
+        this.indexList = indexList;
+    }
+
+    Index set(String key, String value, TreeNode node) {
+        TreeMap<String, TreeMap<String, List<TreeNode>>> newIndexList = indexList;
+        if (key == null) {
+            return this;
+        }
+        Optional<TreeMap<String, List<TreeNode>>> indexOp = indexList.get(key);
+        if (!indexOp.isPresent()) {
+            TreeMap<String, List<TreeNode>> index = new TreeMap<>();
+            List<TreeNode> nodeList = new List<>();
+            nodeList = nodeList.addLast(node);
+            TreeMap<String, List<TreeNode>> newIndex = index.put(value, nodeList);
+            newIndexList = newIndexList.put(key, newIndex);
+            return new Index(newIndexList);
+        }
+
+        TreeMap<String, List<TreeNode>> index = indexOp.get();
+        Optional<List<TreeNode>> nodeListOp = index.get(value);
+
+        List<TreeNode> newNodeList;
+
+        if (nodeListOp.isPresent()) {
+            newNodeList = nodeListOp.get().addLast(node);
+
+        } else {
+            List<TreeNode> nodeList = new List<>();
+            newNodeList = nodeList.addLast(node);
+
+        }
+        TreeMap<String, List<TreeNode>> newIndex = index.put(value, newNodeList);
+        newIndexList = newIndexList.put(key, newIndex);
+
+        return new Index(newIndexList);
+    }
+
+    public Iterator<TreeNode> get(String key, String value) {
+        Optional<TreeMap<String, List<TreeNode>>> indexOp = indexList.get(key);
+        if (!indexOp.isPresent())
+            return null;
+
+        TreeMap<String, List<TreeNode>> index = indexOp.get();
+        Optional<List<TreeNode>> nodeListOp = index.get(value);
+        if (!nodeListOp.isPresent())
+            return new NulIterator<TreeNode>();
+
+        return nodeListOp.get().iterator();
+    }
+
+    public Index delete(TreeNode node) {
+        TreeMap<String, TreeMap<String, List<TreeNode>>> newIndexList = indexList;
+        Attributes attribute = node.getAttributes();
+        Iterator<String> keys = attribute.getKeys();
+        while(keys.hasNext()) {
+            String key = keys.next();
+            String value = attribute.getString(key);
+            Optional<TreeMap<String, List<TreeNode>>> indexOp = newIndexList.get(key);
+            if (!indexOp.isPresent())
+                continue;
+            TreeMap<String, List<TreeNode>> index = indexOp.get();
+            Optional<List<TreeNode>> nodeListOp = index.get(value);
+            if (!nodeListOp.isPresent())
+                continue;
+            List<TreeNode> nodeList = nodeListOp.get();
+            List<TreeNode> newNodeList = nodeList.delete(node);
+            TreeMap<String, List<TreeNode>> newIndex = index.put(value, newNodeList);
+            newIndexList = newIndexList.put(key, newIndex);
+        }
+    return new Index(newIndexList);
+    }
+}
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/IndexCreater.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/IndexCreater.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,27 +1,23 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.store.index;
 
 
-import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 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.data.treemap.TreeMap;
 
 import java.util.Iterator;
-import java.util.Optional;
 import java.util.Stack;
 
 public class IndexCreater {
 
-    TreeNode node;
-    int childNumber;
+    private int childNumber;
     private TreeNodeChildren children;
-    ParentIndex parentIndex = new ParentIndex();
-    TreeMap<String, TreeMap<String, List<TreeNode>>> indexList = new TreeMap<>();
+    private ParentIndex parentIndex = new ParentIndex();
+    private Index index = new Index();
 
     public IndexCreater(TreeNode rootNode) {
         Stack<TreeNode> nodeStack = new Stack<>();
         Stack<Integer> searchStack = new Stack<>();
-        this.node = rootNode;
+        TreeNode node = rootNode;
         while (node != null) {
             TreeNode targetNode = node;
             Iterator<String> keys = targetNode.getAttributes().getKeys();
@@ -29,7 +25,7 @@
                 String key = keys.next();
                 String value = targetNode.getAttributes().getString(key);
                 if (value != null)
-                    indexList = set(key, value, targetNode);
+                    index.set(key, value, targetNode);
             }
             if (node.getChildren().size() > 0) {
                 nodeStack.push(node);
@@ -75,40 +71,10 @@
         }
     }
 
-    public TreeMap<String, TreeMap<String, List<TreeNode>>> set(String key, String value, TreeNode node) {
-        if (key == null)
-            System.out.println("");
-        Optional<TreeMap<String, List<TreeNode>>> indexOp = indexList.get(key);
-        if (!indexOp.isPresent()) {
-            TreeMap<String, List<TreeNode>> index = new TreeMap<>();
-            List<TreeNode> nodeList = new List<>();
-            nodeList = nodeList.addLast(node);
-            TreeMap newIndex = index.put(value, nodeList);
-            indexList = indexList.put(key, newIndex);
-            return indexList;
-        }
 
-        TreeMap<String, List<TreeNode>> index = indexOp.get();
-        Optional<List<TreeNode>> nodeListOp = index.get(value);
 
-        List<TreeNode> newNodeList;
-
-        if (nodeListOp.isPresent()) {
-            newNodeList = nodeListOp.get().addLast(node);
-
-        } else {
-            List<TreeNode> nodeList = new List<>();
-            newNodeList = nodeList.addLast(node);
-
-        }
-        TreeMap newIndex = index.put(value, newNodeList);
-        indexList = indexList.put(key, newIndex);
-
-        return indexList;
-    }
-
-    public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex() {
-        return indexList;
+    public Index getIndex() {
+        return index;
     }
 
     public ParentIndex getParentIndex() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/IndexUpdater.java	Fri Dec 30 03:55:55 2016 +0900
@@ -0,0 +1,69 @@
+package jp.ac.u_ryukyu.ie.cr.jungle.store.index;
+
+import jp.ac.u_ryukyu.ie.cr.jungle.core.Attributes;
+import jp.ac.u_ryukyu.ie.cr.jungle.core.Children;
+import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
+import jp.ac.u_ryukyu.ie.cr.jungle.util.Pair;
+
+import java.util.Iterator;
+import java.util.Optional;
+
+
+public class IndexUpdater {
+    private final TreeNode root;
+
+    public IndexUpdater(TreeNode root) {
+        this.root = root;
+    }
+
+    public Pair<Index, ParentIndex> update(List<TreeNode> editedNodeList, Index index, ParentIndex parentIndex) {
+        Index newIndex = index;
+        ParentIndex newParentIndex = parentIndex;
+        delete(editedNodeList, parentIndex, newIndex, newParentIndex);
+        return put(root, newIndex, newParentIndex);
+    }
+
+    private Pair<Index,ParentIndex> put(TreeNode currentNode, Index newIndex, ParentIndex newParentIndex) {
+        Children children = currentNode.getChildren();
+        for (TreeNode child : children) {
+            if (newParentIndex.contain(child))
+                return new Pair<Index,ParentIndex>(newIndex,newParentIndex);
+            newParentIndex = newParentIndex.set(currentNode, child);
+            Pair<Index,ParentIndex> pair = put(child, newIndex, newParentIndex);
+            newIndex = pair.left();
+            newParentIndex = pair.right();
+        }
+        Attributes attribute = currentNode.getAttributes();
+        Iterator<String> keys = attribute.getKeys();
+        while (keys.hasNext()) {
+            String key = keys.next();
+            String value = attribute.getString(key);
+            newIndex = newIndex.set(key, value, currentNode);
+        }
+        System.out.println("end");
+        return new Pair<Index,ParentIndex>(newIndex,newParentIndex);
+    }
+
+
+    private Pair<Index,ParentIndex> delete(List<TreeNode> editedNodeList, ParentIndex parentIndex, Index newIndex, ParentIndex newParentIndex) {
+        for (TreeNode node : editedNodeList) {
+            newParentIndex = newParentIndex.deleteAllChildren(node);
+            Optional<TreeNode> parentOp = parentIndex.get(node);
+            if (parentOp.isPresent())
+                newIndex = newIndex.delete(node);
+            while (parentOp.isPresent()) {
+                TreeNode parent = parentOp.get();
+                ParentIndex tmp = newParentIndex.deleteAllChildren(parent);
+                if (tmp.equals(newParentIndex))
+                    break;
+                newParentIndex = tmp;
+                parentOp = parentIndex.get(node);
+                newIndex = newIndex.delete(node);
+            }
+        }
+        return new Pair<Index,ParentIndex>(newIndex,newParentIndex);
+    }
+}
+
+
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/ParentIndex.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/ParentIndex.java	Fri Dec 30 03:55:55 2016 +0900
@@ -15,6 +15,10 @@
     parentIndex = new TreeMap<>();
   }
 
+  public ParentIndex(TreeMap<TreeNode, TreeNode> parentIndex) {
+    this.parentIndex = parentIndex;
+  }
+
   public boolean isEmpty(){
     return parentIndex.isEmpty();
   }
@@ -24,33 +28,41 @@
   }
 
   public ParentIndex set(TreeNode parent ,TreeNode child) {
-    parentIndex = parentIndex.put(child, parent);
-    return this;
+    TreeMap<TreeNode, TreeNode> newParentIndex = parentIndex.put(child, parent);
+    return new ParentIndex(newParentIndex);
   }
 
-  public ParentIndex delete(TreeNode child) {
-    parentIndex = parentIndex.delete(child);
-    return this;
+  public boolean contain(TreeNode child){
+    return parentIndex.contain(child);
+  }
+
+  private ParentIndex delete(TreeNode child) {
+    TreeMap<TreeNode, TreeNode> newParentIndex = parentIndex.delete(child);
+    return new ParentIndex(newParentIndex);
   }
 
   public ParentIndex deleteAllChildren(TreeNode parentNode) {
     TreeNodeChildren children = parentNode.getChildren();
     Iterator<TreeNode> childrenIterator = children.iterator();
+    TreeMap<TreeNode, TreeNode> newParentIndex = parentIndex;
     for (; childrenIterator.hasNext();) {
       TreeNode child = childrenIterator.next();
-      parentIndex = parentIndex.delete(child);
+      TreeMap<TreeNode,TreeNode> tmp  = newParentIndex.delete(child);//削除するノードが無かった場合、同じオブジェクトを返す
+      if (tmp.equals(newParentIndex))  //同じオブジェクトだった場合、今のノードとその全ての子ノードはParentIndexに登録されてないから抜ける
+        return this;
     }
-    return this;
+    return new ParentIndex(newParentIndex);
   }
 
   public ParentIndex addAllChildren(TreeNode parentNode) {
     TreeNodeChildren children = parentNode.getChildren();
     Iterator<TreeNode> childrenIterator = children.iterator();
+    TreeMap<TreeNode, TreeNode> newParentIndex = parentIndex;
     for (; childrenIterator.hasNext();) {
       TreeNode child = childrenIterator.next();
-      parentIndex = parentIndex.put(child, parentNode);
+      newParentIndex = newParentIndex.put(child, parentNode);
     }
-    return this;
+    return new ParentIndex(newParentIndex);
   }
 
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/logger/LoggingNode.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/logger/LoggingNode.java	Fri Dec 30 03:55:55 2016 +0900
@@ -8,59 +8,67 @@
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 
 
-public class LoggingNode
-{
-  
-  private final TreeNode wrap;
-  private final OperationLog log;
-  
-	public LoggingNode(TreeNode _wrap)
-	{
-		this(_wrap,new DefaultOperationLog());
-	}
-	
-	public LoggingNode(TreeNode _wrap,OperationLog _log)
-	{
-		wrap = _wrap;
-		log = _log;
-	}
-	
-	public LoggingAttributes getAttributes()
-	{
-		return new LoggingAttributes(wrap,log);
-	}
-	
-	public LoggingChildren getChildren()
-	{
-		return new LoggingChildren(wrap,log);
-	}
-	
+public class LoggingNode {
+
+    private final TreeNode wrap;
+    private final OperationLog log;
+    private TreeNode editedNode;
+
+    public LoggingNode(TreeNode _wrap) {
+        this(_wrap, new DefaultOperationLog());
+    }
+
+    public LoggingNode(TreeNode _wrap, OperationLog _log) {
+        this.wrap = _wrap;
+        this.log = _log;
+    }
+
+    public LoggingNode(TreeNode wrap,TreeNode editedNode, OperationLog log) {
+        this.wrap = wrap;
+        this.log = log;
+        this.editedNode = editedNode;
+    }
+
+
+    public LoggingAttributes getAttributes() {
+        return new LoggingAttributes(wrap, log);
+    }
+
+    public LoggingChildren getChildren() {
+        return new LoggingChildren(wrap, log);
+    }
 
-	public OperationLog getOperationLog()
-	{
-		return log;
-	}
-	
+    public OperationLog getOperationLog() {
+        return log;
+    }
+
 
-  public Either<Error, LoggingNode> replaceNewRootNode() {
-   NodeOperation replaceRootNode = new ReplaceRootNodeOperation();
-   return edit(replaceRootNode);
-  }
+    public Either<Error, LoggingNode> replaceNewRootNode() {
+        NodeOperation replaceRootNode = new ReplaceRootNodeOperation();
+        return edit(replaceRootNode);
+    }
+
+    public Either<Error, LoggingNode> edit(NodeOperation op) {
+        Either<Error, TreeNode> either = op.invoke(wrap);
+        if (either.isA()) {
+            return DefaultEither.newA(either.a());
+        }
 
-  public Either<Error, LoggingNode> edit(NodeOperation op){
-    Either<Error,TreeNode> either = op.invoke(wrap);
-    if(either.isA()){
-      return DefaultEither.newA(either.a());
+        TreeNode newWrap = either.b();
+        OperationLog newLog = log.add(op);
+        LoggingNode newLoggingNode = new LoggingNode(newWrap, newLog);
+        return DefaultEither.newB(newLoggingNode);
+    }
+
+    public TreeNode getWrap() {
+        return wrap;
     }
-    
-    TreeNode newWrap = either.b();
-    OperationLog newLog = log.add(op);
-    LoggingNode newLoggingNode = new LoggingNode(newWrap,newLog);
-    return DefaultEither.newB(newLoggingNode);
-  }
-  
-  public TreeNode getWrap()
-  {
-    return wrap;
-  }
+
+    public void setEditedNode(TreeNode editedNode) {
+        this.editedNode = editedNode;
+    }
+
+    public TreeNode getEditedNode(){
+        return editedNode;
+    }
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/AppendChildAt.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/AppendChildAt.java	Fri Dec 30 03:55:55 2016 +0900
@@ -7,38 +7,35 @@
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
 
-public class AppendChildAt implements NodeEditor
-{
-	private final int pos;
-	
-	public AppendChildAt(int _pos)
-	{
-		pos = _pos;
-	}
+public class AppendChildAt implements NodeEditor {
+    private final int pos;
+
+    public AppendChildAt(int _pos) {
+        pos = _pos;
+    }
 
-	public Either<Error, LoggingNode> _edit(LoggingNode _e) 
-	{
-		Either<Error,LoggingNode> either = _e.getChildren().addNewChildAt(pos);
-		if(either.isA()){
-			// error
-			return either;
-		}
-		return DefaultEither.newB(either.b());
-	}
-	
-	@Override
-	public Either<Error, LoggingNode> edit(TreeNode _e) {
-		LoggingNode logNode = wrap(_e);
-		return _edit(logNode);
-	}
+    public Either<Error, LoggingNode> _edit(LoggingNode _e) {
+        Either<Error, LoggingNode> either = _e.getChildren().addNewChildAt(pos);
+        if (either.isA()) {
+            // error
+            return either;
+        }
+        return DefaultEither.newB(either.b());
+    }
 
-	public LoggingNode wrap(TreeNode node) {
-		return new LoggingNode(node);
-	}
+    @Override
+    public Either<Error, LoggingNode> edit(TreeNode _e) {
+        LoggingNode logNode = wrap(_e);
+        return _edit(logNode);
+    }
 
-	@Override
-	public LoggingNode wrap(TreeNode node, OperationLog op) {
-		return new LoggingNode(node, op);
-	}
+    @Override
+    public LoggingNode wrap(TreeNode newRoot, TreeNode editedNode, OperationLog operationLog) {
+        return new LoggingNode(newRoot,editedNode, operationLog);
+    }
+
+    public LoggingNode wrap(TreeNode node) {
+        return new LoggingNode(node);
+    }
 
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/DeleteAttribute.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/DeleteAttribute.java	Fri Dec 30 03:55:55 2016 +0900
@@ -37,7 +37,7 @@
 	}
 
 	@Override
-	public LoggingNode wrap(TreeNode node, OperationLog op) {
-		return new LoggingNode(node, op);
+	public LoggingNode wrap(TreeNode newRoot, TreeNode editedNode, OperationLog operationLog) {
+		return new LoggingNode(newRoot,editedNode, operationLog);
 	}
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/DeleteChildAt.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/DeleteChildAt.java	Fri Dec 30 03:55:55 2016 +0900
@@ -37,8 +37,8 @@
 	}
 
 	@Override
-	public LoggingNode wrap(TreeNode node, OperationLog op) {
-		return new LoggingNode(node, op);
+	public LoggingNode wrap(TreeNode newRoot, TreeNode editedNode, OperationLog operationLog) {
+		return new LoggingNode(newRoot,editedNode, operationLog);
 	}
 
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/MoveChild.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/MoveChild.java	Fri Dec 30 03:55:55 2016 +0900
@@ -39,7 +39,7 @@
 	}
 
 	@Override
-	public LoggingNode wrap(TreeNode node, OperationLog op) {
-		return new LoggingNode(node, op);
+	public LoggingNode wrap(TreeNode newRoot, TreeNode editedNode, OperationLog operationLog) {
+		return new LoggingNode(newRoot,editedNode, operationLog);
 	}
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/NodeEditor.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/NodeEditor.java	Fri Dec 30 03:55:55 2016 +0900
@@ -10,5 +10,5 @@
 public interface NodeEditor
 {
 	public Either<Error,LoggingNode> edit(TreeNode _e);
-	public LoggingNode wrap(TreeNode node, OperationLog op);
+	public LoggingNode wrap(TreeNode newRoot, TreeNode editedNode, OperationLog operationLog);
 }
\ No newline at end of file
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/PutAttribute.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/PutAttribute.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,14 +1,14 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.store.trasnformer;
 
-import java.nio.ByteBuffer;
-
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.LoggingNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.OperationLog;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
 
+import java.nio.ByteBuffer;
+
 public class PutAttribute implements NodeEditor
 {
 	private final String key;
@@ -41,8 +41,8 @@
 	}
 
 	@Override
-	public LoggingNode wrap(TreeNode node, OperationLog op) {
-		return new LoggingNode(node, op);
+	public LoggingNode wrap(TreeNode node,TreeNode editedNode, OperationLog op) {
+		return new LoggingNode(node,editedNode, op);
 	}
 
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/replaceRootNodeAt.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/trasnformer/replaceRootNodeAt.java	Fri Dec 30 03:55:55 2016 +0900
@@ -31,10 +31,10 @@
     return new LoggingNode(node);
   }
 
- 
+
   @Override
-  public LoggingNode wrap(TreeNode node, OperationLog op) {
-    return new LoggingNode(node, op);
+  public LoggingNode wrap(TreeNode newRoot, TreeNode editedNode, OperationLog operationLog) {
+    return new LoggingNode(newRoot,editedNode, operationLog);
   }
 
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/DefaultTreeContext.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/DefaultTreeContext.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,14 +1,13 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.transaction;
 
 
-import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeList;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.TreeContext;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.Index;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.operations.TreeOperation;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.operations.TreeOperation;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap;
 
 public class DefaultTreeContext implements TreeContext {
     private final TreeNode root;
@@ -76,7 +75,7 @@
     }
 
     @Override
-    public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex() {
+    public Index getIndex() {
         return traverser.getIndex();
     }
 
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/DifferenceTreeContext.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/DifferenceTreeContext.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,12 +1,11 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.transaction;
 
-import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap;
 import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeList;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.TreeContext;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.Index;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.operations.TreeOperation;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
 
 
@@ -82,7 +81,7 @@
     }
 
     @Override
-    public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex() {
+    public Index getIndex() {
         return traverser.getIndex();
     }
 
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/editor/jungleTreeEditor/DefaultJungleTreeEditor.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/editor/jungleTreeEditor/DefaultJungleTreeEditor.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,5 +1,6 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor;
 
+import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.DefaultTreeOperationLog;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.LoggingNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.OperationLog;
@@ -20,115 +21,107 @@
 
 import java.nio.ByteBuffer;
 
-public class DefaultJungleTreeEditor implements JungleTreeEditor
-{
-	private final TransactionManager txManager;
-	private final TreeNode root;
-	private final TreeEditor editor;
-	private final TreeOperationLog log;
-
-	public DefaultJungleTreeEditor(TreeNode _root,TransactionManager _txManager,TreeEditor _editor)
-	{
-		this(_root,_txManager,_editor,new DefaultTreeOperationLog());
-	}
-	
-	
-	
-	public DefaultJungleTreeEditor(TreeNode newNode,TransactionManager _txManager,TreeEditor _editor,TreeOperationLog _log)
-	{
-		this.root = newNode;
-		this.txManager = _txManager;
-		this.editor = _editor;
-		this.log = _log;
-	}
-	
-	private Either<Error,JungleTreeEditor> _edit(final NodePath _path,NodeEditor _e)
-	{
-		Either<Error, LoggingNode> editEither = editor.edit(root, _path, _e);
-
-		if(editEither.isA()){
-			return DefaultEither.newA(editEither.a());
-		}
 
-		LoggingNode newLogging = editEither.b();
-		OperationLog newLog = newLogging.getOperationLog();
-		TreeNode newNode = newLogging.getWrap();
-		
-		IterableConverter.Converter<TreeOperation,NodeOperation> converter = new IterableConverter.Converter<TreeOperation,NodeOperation>(){
-			@Override
-			public TreeOperation conv(NodeOperation _b){
-				return new DefaultTreeOperation(_path,_b);
-			}
-		};
-		
-		Iterable<TreeOperation> iterable = new IterableConverter<>(newLog,converter);
-		DefaultTreeOperationLog treeOperationLog = new DefaultTreeOperationLog(iterable,newLog.length());
-		TreeOperationLog newTreeOpLog = log.append(treeOperationLog);
-		JungleTreeEditor newEditor = new DefaultJungleTreeEditor(newNode,txManager,editor,newTreeOpLog);
-		return DefaultEither.newB(newEditor);
-	}
-	
-	 @Override
-	  public Either<Error,JungleTreeEditor> replaceNewRootNode()
-	  {
-	   ReplaceRootNodeAt appendChildAt = new ReplaceRootNodeAt();
-	    return _edit(new DefaultNodePath(),appendChildAt);
-	  }
-	
-	@Override
-	public Either<Error,JungleTreeEditor> addNewChildAt(NodePath _path, int _pos)
-	{
-		AppendChildAt appendChildAt = new AppendChildAt(_pos);
-		return _edit(_path,appendChildAt);
-	}
+public class DefaultJungleTreeEditor implements JungleTreeEditor {
+    private final TransactionManager txManager;
+    private final TreeNode root;
+    private final TreeEditor editor;
+    private final TreeOperationLog log;
+    private final List<TreeNode> editedNodeList;
 
-	@Override
-	public Either<Error,JungleTreeEditor> deleteChildAt(NodePath _path, int _pos)
-	{
-		DeleteChildAt deleteChildAt = new DeleteChildAt(_pos);
-		return _edit(_path,deleteChildAt);
-	}
-
-	@Override
-	public Either<Error,JungleTreeEditor> putAttribute(NodePath _path,String _key,ByteBuffer _value)
-	{
-		PutAttribute putAttribute = new PutAttribute(_key,_value);
-		return _edit(_path,putAttribute);
-	}
-
-	@Override
-	public Either<Error,JungleTreeEditor> deleteAttribute(NodePath _path, String _key)
-	{
-		DeleteAttribute deleteAttribute = new DeleteAttribute(_key);
-		return _edit(_path,deleteAttribute);
-	}
-
-	@Override
-	public Either<Error, JungleTreeEditor> moveChild(NodePath path,int childNum, String move) {
-		MoveChild movechild = new MoveChild(move, childNum);
-		return _edit(path,movechild);
-	}
+    public DefaultJungleTreeEditor(TreeNode _root, TransactionManager _txManager, TreeEditor _editor) {
+        this(_root, _txManager, _editor, new DefaultTreeOperationLog(), new List<>());
+    }
 
 
-	@Override
-	public Either<Error,JungleTreeEditor> edit(NodePath _path,NodeEditor _editor)
-	{
-		return _edit(_path,_editor);
-	}
+    public DefaultJungleTreeEditor(TreeNode newNode, TransactionManager _txManager, TreeEditor _editor, TreeOperationLog _log, List<TreeNode> editedNodeList) {
+        this.root = newNode;
+        this.txManager = _txManager;
+        this.editor = _editor;
+        this.log = _log;
+        this.editedNodeList = editedNodeList;
+    }
+
+    private Either<Error, JungleTreeEditor> _edit(final NodePath _path, NodeEditor _e) {
+        Either<Error, LoggingNode> editEither = editor.edit(root, _path, _e);
+
+        if (editEither.isA()) {
+            return DefaultEither.newA(editEither.a());
+        }
+
+        LoggingNode newLogging = editEither.b();
+        OperationLog newLog = newLogging.getOperationLog();
+        TreeNode newNode = newLogging.getWrap();
+        TreeNode editedNode = newLogging.getEditedNode();
+        List<TreeNode> newEditendNodeList = editedNodeList.add(0,editedNode);
+        IterableConverter.Converter<TreeOperation, NodeOperation> converter = new IterableConverter.Converter<TreeOperation, NodeOperation>() {
+            @Override
+            public TreeOperation conv(NodeOperation _b) {
+                return new DefaultTreeOperation(_path, _b);
+            }
+        };
+
+        Iterable<TreeOperation> iterable = new IterableConverter<>(newLog, converter);
+        DefaultTreeOperationLog treeOperationLog = new DefaultTreeOperationLog(iterable, newLog.length());
+        TreeOperationLog newTreeOpLog = log.append(treeOperationLog);
+        JungleTreeEditor newEditor = new DefaultJungleTreeEditor(newNode, txManager, editor, newTreeOpLog, newEditendNodeList);
+        return DefaultEither.newB(newEditor);
+    }
+
+    @Override
+    public Either<Error, JungleTreeEditor> replaceNewRootNode() {
+        ReplaceRootNodeAt appendChildAt = new ReplaceRootNodeAt();
+        return _edit(new DefaultNodePath(), appendChildAt);
+    }
 
-	@Override
-	public Either<Error,JungleTreeEditor> success()
-	{
-		Either<Error,TransactionManager> either = txManager.commit(root,log);
-		if(either.isA()){
-			return DefaultEither.newA(either.a());
-		}
-		
-		TransactionManager newTxManager = either.b();
-		JungleTreeEditor newTreeEditor = new DefaultJungleTreeEditor(root,newTxManager,editor);
-		
-		return DefaultEither.newB(newTreeEditor);
-	}
+    @Override
+    public Either<Error, JungleTreeEditor> addNewChildAt(NodePath _path, int _pos) {
+        AppendChildAt appendChildAt = new AppendChildAt(_pos);
+        return _edit(_path, appendChildAt);
+    }
+
+    @Override
+    public Either<Error, JungleTreeEditor> deleteChildAt(NodePath _path, int _pos) {
+        DeleteChildAt deleteChildAt = new DeleteChildAt(_pos);
+        return _edit(_path, deleteChildAt);
+    }
+
+    @Override
+    public Either<Error, JungleTreeEditor> putAttribute(NodePath _path, String _key, ByteBuffer _value) {
+        PutAttribute putAttribute = new PutAttribute(_key, _value);
+        return _edit(_path, putAttribute);
+    }
+
+    @Override
+    public Either<Error, JungleTreeEditor> deleteAttribute(NodePath _path, String _key) {
+        DeleteAttribute deleteAttribute = new DeleteAttribute(_key);
+        return _edit(_path, deleteAttribute);
+    }
+
+    @Override
+    public Either<Error, JungleTreeEditor> moveChild(NodePath path, int childNum, String move) {
+        MoveChild movechild = new MoveChild(move, childNum);
+        return _edit(path, movechild);
+    }
+
+
+    @Override
+    public Either<Error, JungleTreeEditor> edit(NodePath _path, NodeEditor _editor) {
+        return _edit(_path, _editor);
+    }
+
+    @Override
+    public Either<Error, JungleTreeEditor> success() {
+        Either<Error, TransactionManager> either = txManager.commit(root, log, editedNodeList);
+        if (either.isA()) {
+            return DefaultEither.newA(either.a());
+        }
+
+        TransactionManager newTxManager = either.b();
+        JungleTreeEditor newTreeEditor = new DefaultJungleTreeEditor(root, newTxManager, editor);
+
+        return DefaultEither.newB(newTreeEditor);
+    }
 
     @Override
     public Either<Error, JungleTreeEditor> flushSuccess() {
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/editor/jungleTreeEditor/DifferenceJungleTreeEditor.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/editor/jungleTreeEditor/DifferenceJungleTreeEditor.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,5 +1,6 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor;
 
+import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.DefaultTreeOperationLog;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.LoggingNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.OperationLog;
@@ -33,6 +34,7 @@
     private final TreeOperationLog log;
     private final TreeNode subTreeRoot;
     private TreeNode appendedNode;
+    private final List<TreeNode> editedNodeList = new List<>();
 
     public DifferenceJungleTreeEditor(TreeNode subTreeRoot, TransactionManager txManager, TreeEditor editor) {
         this(subTreeRoot, subTreeRoot, txManager, editor, new DefaultTreeOperationLog());
@@ -128,7 +130,7 @@
 
     @Override
     public Either<Error, JungleTreeEditor> success() {
-        Either<Error, TransactionManager> either = txManager.commit(subTreeRoot, log);
+        Either<Error, TransactionManager> either = txManager.commit(subTreeRoot, log,editedNodeList);
         if (either.isA()) {
             return DefaultEither.newA(either.a());
         }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/editor/treeEditor/DefaultTreeEditor.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/editor/treeEditor/DefaultTreeEditor.java	Fri Dec 30 03:55:55 2016 +0900
@@ -37,7 +37,7 @@
             return DefaultEither.newA(either.a());
         }
         LoggingNode newWrap = either.b();
-
+        newWrap.setEditedNode(target);
         return clone(newWrap, traversal, editor);
     }
 
@@ -66,7 +66,7 @@
         }
 
         TreeNode newRoot = child;
-        LoggingNode logNode = editor.wrap(newRoot, newWrap.getOperationLog());
+        LoggingNode logNode = editor.wrap(newRoot,newWrap.getEditedNode(), newWrap.getOperationLog());
         return DefaultEither.newB(logNode);
     }
 
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DefaultTransactionManager.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DefaultTransactionManager.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,17 +1,18 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.transaction.manager;
 
 
+import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
+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.logger.TreeOperationLog;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.operations.TreeOperation;
-import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeList;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.DefaultTreeContext;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither;
+import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.DefaultError;
-import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
 
 import java.util.Iterator;
@@ -32,7 +33,7 @@
 
 
     @Override
-    public Either<Error, TransactionManager> commit(TreeNode newRoot, final TreeOperationLog _log) {
+    public Either<Error, TransactionManager> commit(TreeNode newRoot, final TreeOperationLog _log,List<TreeNode> editNodeList) {
         long currentRevision = tip.revision();
         long nextRevision = currentRevision + 1;
 
@@ -61,7 +62,7 @@
         };
 
         InterfaceTraverser traverser = new InterfaceTraverser(newRoot, true);
-        traverser.createIndex();
+        traverser.updateIndex(editNodeList);
         TreeContext newTreeContext = new DefaultTreeContext(newRoot, tip, list, uuid, _treeName, nextRevision, traverser);
 
         if (repository.compareAndSet(newTreeContext.prev(), newTreeContext)) {
@@ -74,7 +75,7 @@
 
     @Override
     public Either<Error, TransactionManager> flashCommit(TreeNode _newRoot, TreeOperationLog _log) {
-        return commit(_newRoot, _log);
+        return null;//commit(_newRoot, _log);
     }
 
     @Override
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DifferenceTransactionManager.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DifferenceTransactionManager.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,5 +1,6 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.transaction.manager;
 
+import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 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;
@@ -37,7 +38,7 @@
     }
 
     @Override
-    public Either<Error, TransactionManager> commit(TreeNode subTreeRoot, TreeOperationLog log) {
+    public Either<Error, TransactionManager> commit(TreeNode subTreeRoot, TreeOperationLog log,List<TreeNode> editNodeList) {
         long currentRevision = tip.revision();
         long nextRevision = currentRevision + 1;
         NodeOperation commitOperation = new Commit();
@@ -95,7 +96,7 @@
 
     @Override
     public Either<Error, TransactionManager> flashCommit(TreeNode _newRoot, TreeOperationLog _log) {
-        return commit(_newRoot, _log);
+        return null;//commit(_newRoot, _log);
     }
 
     @Override
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/TransactionManager.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/TransactionManager.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,14 +1,17 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.transaction.manager;
 
 
+import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.TreeOperationLog;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
 
+
+
 public interface TransactionManager
 {
-	public Either<Error,TransactionManager> commit(TreeNode _newRoot,TreeOperationLog _log);
+	public Either<Error,TransactionManager> commit(TreeNode _newRoot, TreeOperationLog _log,List<TreeNode> editNodeList);
     public Either<Error,TransactionManager> flashCommit(TreeNode _newRoot,TreeOperationLog _log);
 	public boolean setAppendedNode(TreeNode appendedNode);
 	public String getUUID();
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/node/TreeNodeAttributes.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/node/TreeNodeAttributes.java	Fri Dec 30 03:55:55 2016 +0900
@@ -5,14 +5,9 @@
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
 
 import java.nio.ByteBuffer;
-import java.util.Iterator;
-import java.util.List;
 
 public interface TreeNodeAttributes extends Attributes
 {
 	public Either<Error,TreeNode> delete(String key);
 	public Either<Error,TreeNode> put(String key, ByteBuffer value);
-	public Iterator<String> getKeys();
-	public boolean contain(String key);
-	public Iterator<String> getFilteringKey(List<String> filter);
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/traverser/InterfaceTraverser.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/traverser/InterfaceTraverser.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,42 +1,40 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.traverser;
 
-import jp.ac.u_ryukyu.ie.cr.jungle.store.NulIterator;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 import jp.ac.u_ryukyu.ie.cr.jungle.query.JungleNodeIterator;
 import jp.ac.u_ryukyu.ie.cr.jungle.query.Query;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.Index;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.index.IndexCreater;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.IndexUpdater;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
+import jp.ac.u_ryukyu.ie.cr.jungle.util.Pair;
 
 import java.util.Iterator;
-import java.util.Optional;
 
 public class InterfaceTraverser {
 
-    TreeNode root;
-    TreeMap<String, TreeMap<String, List<TreeNode>>> indexList;
-    ParentIndex parentIndex;
-    boolean parentUpdateFlag;
-    boolean useIndex;
+    private TreeNode root;
+    private Index index;
+    private ParentIndex parentIndex;
+    private IndexUpdater indexUpdater;
+    private boolean parentUpdateFlag;
+    private boolean useIndex;
 
     public InterfaceTraverser(TreeNode root, boolean indexFlag) {
-        this(root, new TreeMap<>(), new ParentIndex(), indexFlag);
+        this(root, new Index(), new ParentIndex(), indexFlag);
     }
 
-    public InterfaceTraverser(TreeNode root, TreeMap<String, TreeMap<String, List<TreeNode>>> index, ParentIndex parentIndex, boolean useIndex) {
+    public InterfaceTraverser(TreeNode root, Index index, ParentIndex parentIndex, boolean useIndex) {
         this.root = root;
-        this.indexList = index;
+        this.index = index;
         this.parentIndex = parentIndex;
-        if (parentIndex.isEmpty())
-            parentUpdateFlag = true;
-        else
-            parentUpdateFlag = false;
         this.useIndex = useIndex;
+        this.indexUpdater = new IndexUpdater(root);
     }
 
-    public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex() {
-        return indexList;
+    public Index getIndex() {
+        return index;
     }
 
     public void commit() {
@@ -48,14 +46,16 @@
     }
 
     public void createIndex() {
-        // long t1 = System.currentTimeMillis();
         IndexCreater creater = new IndexCreater(root);
-        // long t2 = System.currentTimeMillis();
-        // System.out.println("createIndex time = " + (t2 - t1));
-        indexList = creater.getIndex();
+        index = creater.getIndex();
         parentIndex = creater.getParentIndex();
     }
 
+    public void updateIndex(List<TreeNode> editedNodeList) {
+        Pair<Index,ParentIndex> p = indexUpdater.update(editedNodeList, index, parentIndex);
+        index = p.left();
+        parentIndex = p.right();
+    }
 
     private TreeNode nextmatch(TreeNode node, Query query) {
         if (query.condition(node))
@@ -71,7 +71,7 @@
 
         Iterator<TreeNode> nodeIterator;
         if (key != null && searchValue != null && useIndex) {
-            nodeIterator = get(key, searchValue);
+            nodeIterator = index.get(key, searchValue);
             ;
         } else {
             nodeIterator = new JungleNodeIterator(root);
@@ -116,18 +116,4 @@
 
         };
     }
-
-
-    public Iterator<TreeNode> get(String key, String value) {
-        Optional<TreeMap<String, List<TreeNode>>> indexOp = indexList.get(key);
-        if (!indexOp.isPresent())
-            return null;
-
-        TreeMap<String, List<TreeNode>> index = indexOp.get();
-        Optional<List<TreeNode>> nodeListOp = index.get(value);
-        if (!nodeListOp.isPresent())
-            return new NulIterator<TreeNode>();
-
-        return nodeListOp.get().iterator();
-    }
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/tree/DefaultJungleTree.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/tree/DefaultJungleTree.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,18 +1,17 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.tree;
 
+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.Index;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
+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.DefaultJungleTreeEditor;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap;
-import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeListWriter;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.NodePath;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.TreeContext;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.treeEditor.TreeEditor;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.manager.DefaultTransactionManager;
 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.store.index.ParentIndex;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.DefaultJungleTreeEditor;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.manager.DefaultTransactionManager;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
@@ -98,7 +97,7 @@
     }
 
     @Override
-    public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex() {
+    public Index getIndex() {
         TreeContext tc = repository.get();
         return tc.getIndex();
     }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/tree/JungleTree.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/tree/JungleTree.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,12 +1,11 @@
 package jp.ac.u_ryukyu.ie.cr.jungle.tree;
 
 
-import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.Index;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
 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.store.index.ParentIndex;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
@@ -20,7 +19,7 @@
 
     public Either<Error, JungleTree> getOldTree(long revision);
 
-    public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex();
+    public Index getIndex();
 
     public ParentIndex getParentIndex();
 
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentJungleTree.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentJungleTree.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,21 +1,20 @@
 package jp.ac.u_ryukyu.ie.cr.jungleNetwork.persistent;
 
 
-import jp.ac.u_ryukyu.ie.cr.jungle.tree.DefaultJungleTree;
-import jp.ac.u_ryukyu.ie.cr.jungle.tree.JungleTree;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap;
 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.Index;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
+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.store.TreeContext;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.treeEditor.TreeEditor;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath;
 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.store.index.ParentIndex;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
+import jp.ac.u_ryukyu.ie.cr.jungle.tree.DefaultJungleTree;
+import jp.ac.u_ryukyu.ie.cr.jungle.tree.JungleTree;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
@@ -90,14 +89,14 @@
     }
 
     @Override
-    public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex() {
+    public Index getIndex() {
         TreeContext tc = repository.get();
         return tc.getIndex();
     }
 
     @Override
     public InterfaceTraverser getTraverser(boolean useIndex) {
-        TreeMap<String, TreeMap<String, List<TreeNode>>> index = getIndex();
+        Index index = getIndex();
         ParentIndex parentIndex = getParentIndex();
         return new InterfaceTraverser(getRootNode(), index, parentIndex, useIndex);
     }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentJungleTreeEditor.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentJungleTreeEditor.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,5 +1,6 @@
 package jp.ac.u_ryukyu.ie.cr.jungleNetwork.persistent;
 
+import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.DefaultTreeOperationLog;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.LoggingNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.OperationLog;
@@ -26,7 +27,7 @@
     private final TreeNode root;
     private final TreeEditor editor;
     private final TreeOperationLog log;
-
+    private final List<TreeNode> editedNodeList = new List<>();
 
     public PersistentJungleTreeEditor(TreeNode _root, TransactionManager _txManager, TreeEditor _editor) {
         this(_root, _txManager, _editor, new DefaultTreeOperationLog());
@@ -108,7 +109,7 @@
 
     @Override
     public Either<Error, JungleTreeEditor> success() {
-        Either<Error, TransactionManager> either = txManager.commit(root, log);
+        Either<Error, TransactionManager> either = txManager.commit(root, log,editedNodeList);
         if (either.isA()) {
             return DefaultEither.newA(either.a());
         }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentTransactionManager.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentTransactionManager.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,16 +1,17 @@
 package jp.ac.u_ryukyu.ie.cr.jungleNetwork.persistent;
 
 
+import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 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.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.DefaultTreeOperationLog;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.TreeOperationLog;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.manager.TransactionManager;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither;
+import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.DefaultError;
-import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
 
 import java.util.concurrent.atomic.AtomicReference;
@@ -33,7 +34,7 @@
     }
 
     @Override
-    public Either<Error, TransactionManager> commit(TreeNode _newRoot, final TreeOperationLog _log) {
+    public Either<Error, TransactionManager> commit(TreeNode _newRoot, final TreeOperationLog _log,List<TreeNode> editNodeList) {
         long currentRevision = tip.revision();
         long nextRevision = currentRevision + 1;
 
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentTreeContext.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentTreeContext.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,13 +1,12 @@
 package jp.ac.u_ryukyu.ie.cr.jungleNetwork.persistent;
 
 
-import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap;
 import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeList;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.TreeContext;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.Index;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.operations.TreeOperation;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
 
 public class PersistentTreeContext implements TreeContext {
@@ -75,7 +74,7 @@
     }
 
     @Override
-    public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex() {
+    public Index getIndex() {
         return traverser.getIndex();
     }
 
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transaction/NetworkDefaultJungleTree.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transaction/NetworkDefaultJungleTree.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,20 +1,19 @@
 package jp.ac.u_ryukyu.ie.cr.jungleNetwork.transaction;
 
 
+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.Index;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
+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.editor.treeEditor.TreeEditor;
+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;
 import jp.ac.u_ryukyu.ie.cr.jungle.tree.DefaultJungleTree;
 import jp.ac.u_ryukyu.ie.cr.jungle.tree.JungleTree;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
-import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap;
-import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeListWriter;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.NodePath;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.TreeContext;
-import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.treeEditor.TreeEditor;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath;
-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.store.index.ParentIndex;
-import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
@@ -94,14 +93,14 @@
   }
 
   @Override
-  public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex() {
+  public Index getIndex() {
     TreeContext tc = repository.get();
     return tc.getIndex();
   }
 
   @Override
   public InterfaceTraverser getTraverser(boolean useIndex) {
-    TreeMap<String, TreeMap<String, List<TreeNode>>> index = getIndex();
+    Index index = getIndex();
     ParentIndex parentIndex = getParentIndex();
     return new InterfaceTraverser(getRootNode(), index, parentIndex, useIndex);
   }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transaction/NetworkDefaultJungleTreeEditor.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transaction/NetworkDefaultJungleTreeEditor.java	Fri Dec 30 03:55:55 2016 +0900
@@ -2,6 +2,7 @@
 
 
 import alice.codesegment.CodeSegment;
+import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.DefaultTreeOperationLog;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.LoggingNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.OperationLog;
@@ -33,6 +34,7 @@
 	private final String treeName;
 	private final TreeOperationLog log;
 	private boolean exportLog;
+	private final List<TreeNode> editedNodeList = new List<>();
 
 	public NetworkDefaultJungleTreeEditor(String _treeName, TreeNode _root,TransactionManager _txManager,TreeEditor _editor)
 	{
@@ -134,7 +136,7 @@
 	@Override
 	public Either<Error,JungleTreeEditor> success()
 	{
-		Either<Error,TransactionManager> either = txManager.commit(root,log);
+		Either<Error,TransactionManager> either = txManager.commit(root,log,editedNodeList);
 		if(either.isA()){
 			return DefaultEither.newA(either.a());
 		}
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transaction/NetworkTransactionManager.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transaction/NetworkTransactionManager.java	Fri Dec 30 03:55:55 2016 +0900
@@ -1,18 +1,19 @@
 package jp.ac.u_ryukyu.ie.cr.jungleNetwork.transaction;
 
 
+import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
 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.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.TreeOperationLog;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.operations.TreeOperation;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.DefaultTreeContext;
 import jp.ac.u_ryukyu.ie.cr.jungle.transaction.manager.TransactionManager;
+import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither;
+import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.DefaultError;
-import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
 
 import java.util.Iterator;
@@ -34,7 +35,7 @@
     }
 
     @Override
-    public Either<Error, TransactionManager> commit(TreeNode newRoot, final TreeOperationLog _log) {
+    public Either<Error, TransactionManager> commit(TreeNode newRoot, final TreeOperationLog _log,List<TreeNode> editNodeList) {
         long currentRevision = tip.revision();
         long nextRevision = currentRevision + 1;
 
@@ -76,7 +77,7 @@
 
     @Override
     public Either<Error, TransactionManager> flashCommit(TreeNode _newRoot, TreeOperationLog _log) {
-        return commit(_newRoot, _log);
+        return null;//commit(_newRoot, _log);
     }
 
     @Override
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transformer/NetworkAppendChildAt.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/transformer/NetworkAppendChildAt.java	Fri Dec 30 03:55:55 2016 +0900
@@ -44,8 +44,7 @@
 	}
 
 	@Override
-	public LoggingNode wrap(TreeNode node, OperationLog op) {
-		return new LoggingNode(node, op);
+	public LoggingNode wrap(TreeNode newRoot, TreeNode editedNode, OperationLog operationLog) {
+		return new LoggingNode(newRoot,editedNode, operationLog);
 	}
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/CreateTreeMethod.java	Fri Dec 30 03:55:55 2016 +0900
@@ -0,0 +1,48 @@
+package jp.ac.u_ryukyu.ie.cr.jungle;
+
+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.util.Either;
+import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
+import junit.framework.Assert;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Created by e115731 on 2016/12/28.
+ */
+public class CreateTreeMethod {
+
+    public static JungleTreeEditor createTree(JungleTreeEditor editor, String key, String indexKey, int _maxHeight, NodePath path) {
+        JungleTreeEditor newEditor = createTree(editor, key, indexKey, 0, _maxHeight, path);
+        Either<Error,JungleTreeEditor> either = newEditor.success();
+        if (either.isA())
+            Assert.fail();
+        return either.b();
+    }
+
+    private static JungleTreeEditor createTree(JungleTreeEditor editor, String key, String indexKey, int _curY, int _maxHeight, NodePath path) {
+
+        if (_curY == _maxHeight) {
+            return editor;
+        }
+        for (int i = 0; i < 3; i++) {
+
+            Either<Error, JungleTreeEditor> either = editor.addNewChildAt(path, i);
+            if (either.isA())
+                Assert.fail();
+            editor = either.b();
+            String value = path.add(i).toString();
+            either = editor.putAttribute(path.add(i), key, ByteBuffer.wrap(value.getBytes()));
+            if (either.isA())
+                Assert.fail();
+            editor = either.b();
+            either = editor.putAttribute(path.add(i), indexKey, ByteBuffer.wrap(value.getBytes()));
+            if (either.isA())
+                Assert.fail();
+            editor = either.b();
+            editor = createTree(editor, key, indexKey, _curY + 1, _maxHeight, path.add(i));
+        }
+        return editor;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/index/IndexTest.java	Fri Dec 30 03:55:55 2016 +0900
@@ -0,0 +1,119 @@
+package jp.ac.u_ryukyu.ie.cr.jungle.index;
+
+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.core.Children;
+import jp.ac.u_ryukyu.ie.cr.jungle.query.JungleNodeIterator;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.Index;
+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.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;
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import static jp.ac.u_ryukyu.ie.cr.jungle.CreateTreeMethod.createTree;
+
+
+public class IndexTest {
+
+    @Test
+    public void IndexTests() {
+        String key = "key";
+        String indexKey = "indexKey";
+        String addAttributeKey = "addAttributeKey";
+        Jungle jungle = new DefaultJungle(null, "hogehoge", new DefaultTraverser());
+        jungle.createNewTree("tree");
+        JungleTree tree = jungle.getTreeByName("tree");
+        JungleTreeEditor editor = tree.getJungleTreeEditor();
+        NodePath path = new DefaultNodePath();
+        createTree(editor, key, indexKey, 4, path);
+        TreeNode oldTreeRoot = tree.getRootNode();
+        Index index = tree.getIndex();
+        JungleNodeIterator iterator = new JungleNodeIterator(oldTreeRoot);
+        while (iterator.hasNext()) {
+            TreeNode node = iterator.next();
+            TreeNodeAttributes attribute = node.getAttributes();
+            Iterator<String> keys = attribute.getKeys();
+            while (keys.hasNext()) {
+                String attributeKey = keys.next();
+                String value = attribute.getString(attributeKey);
+                Iterator<TreeNode> indexNode = index.get(attributeKey, value);
+                Assert.assertTrue(indexNode.hasNext());
+                Assert.assertEquals(indexNode.next(),node);
+            }
+        }
+
+        JungleTreeEditor editor2 = tree.getJungleTreeEditor();
+        path = path.add(0).add(0).add(2);
+        Either<Error, JungleTreeEditor> either = editor2.putAttribute(path, addAttributeKey, ByteBuffer.wrap("value1".getBytes()));
+        Assert.assertFalse(either.isA());
+        JungleTreeEditor editor3 = either.b();
+        NodePath path2 = new DefaultNodePath();
+        path2 = path2.add(1).add(1).add(2);
+        Either<Error, JungleTreeEditor> either2 = editor3.putAttribute(path2, addAttributeKey, ByteBuffer.wrap("value2".getBytes()));
+        Assert.assertFalse(either2.isA());
+        JungleTreeEditor editor4 = either2.b();
+        Either<Error, JungleTreeEditor> either3 = editor4.success();
+        Assert.assertFalse(either3.isA());
+
+        TreeNode newTreeRoot = tree.getRootNode();
+        Index newIndex = tree.getIndex();
+        iterator = new JungleNodeIterator(newTreeRoot);
+        while (iterator.hasNext()) {
+            TreeNode node = iterator.next();
+            TreeNodeAttributes attribute = node.getAttributes();
+            Iterator<String> keys = attribute.getKeys();
+            while (keys.hasNext()) {
+                String attributeKey = keys.next();
+                String value = attribute.getString(attributeKey);
+                System.out.println(value);
+                if (value.equals("<-1,1,1,2>"))
+                    System.out.println(value);
+                Iterator<TreeNode> indexNode = newIndex.get(attributeKey, value);
+                Assert.assertTrue(indexNode.hasNext());
+                Assert.assertEquals(indexNode.next(),node);
+            }
+        }
+
+        List<TreeNode> deletedNodeList = new LinkedList<>();
+        deletedNodeList = getDeletedNodeList(deletedNodeList, oldTreeRoot, path);
+        deletedNodeList = getDeletedNodeList(deletedNodeList, oldTreeRoot, path2);
+
+        for (TreeNode deletedNode : deletedNodeList) {
+            TreeNodeAttributes attribute = deletedNode.getAttributes();
+            Iterator<String> keys = attribute.getKeys();
+            while (keys.hasNext()) {
+                String attributeKey = keys.next();
+                String value = attribute.getString(key);
+                Iterator<TreeNode> indexNode = newIndex.get(attributeKey, value);
+                Assert.assertTrue(indexNode.hasNext());
+                Assert.assertNotEquals(indexNode.next(),deletedNode);
+            }
+        }
+    }
+
+    private List<TreeNode> getDeletedNodeList(List<TreeNode> list, TreeNode oldTreeRoot, NodePath path) {
+        TreeNode node = oldTreeRoot;
+        for (Integer i : path.pop().right()) {
+            Children children = node.getChildren();
+            Either<Error, TreeNode> either = children.at(i);
+            Assert.assertFalse(either.isA());
+            node = either.b();
+            list.add(node);
+        }
+        return list;
+    }
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/index/ParentIndexPutTest.java	Fri Dec 30 03:55:55 2016 +0900
@@ -0,0 +1,104 @@
+package jp.ac.u_ryukyu.ie.cr.jungle.index;
+
+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.core.Children;
+import jp.ac.u_ryukyu.ie.cr.jungle.query.JungleNodeIterator;
+import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
+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.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;
+
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+
+import static jp.ac.u_ryukyu.ie.cr.jungle.CreateTreeMethod.createTree;
+
+
+/**
+ * Created by e115731 on 15/05/06.
+ */
+public class ParentIndexPutTest {
+    private String key = "key";
+    private String indexKey = "indexKey";
+    private String addAttributeKey = "addAttributeKey";
+    @Test
+    public void ParentIndexPut() {
+        Jungle jungle = new DefaultJungle(null, "hogehoge",new DefaultTraverser());
+        jungle.createNewTree("tree");
+        JungleTree tree = jungle.getTreeByName("tree");
+        JungleTreeEditor editor = tree.getJungleTreeEditor();
+        NodePath path = new DefaultNodePath();
+        createTree(editor,key,indexKey,4,path);
+        TreeNode oldTreeRoot = tree.getRootNode();
+        ParentIndex parentIndex = tree.getParentIndex();
+        JungleNodeIterator iterator = new JungleNodeIterator(oldTreeRoot);
+        Assert.assertTrue(iterator.hasNext());
+        TreeNode node = iterator.next();
+        Assert.assertEquals(oldTreeRoot,node); //初めはrootなのでParentIndexは存在しない
+        while(iterator.hasNext()){
+            TreeNode child = iterator.next();
+            Optional<TreeNode> parentOp = parentIndex.get(child);
+            Assert.assertTrue(parentOp.isPresent());
+            System.out.println(parentOp.get());
+        }
+
+        JungleTreeEditor editor2 = tree.getJungleTreeEditor();
+        path = path.add(0).add(0).add(2);
+        Either<Error, JungleTreeEditor> either = editor2.putAttribute(path,addAttributeKey, ByteBuffer.wrap("value".getBytes()) );
+        Assert.assertFalse(either.isA());
+        JungleTreeEditor editor3 = either.b();
+        NodePath path2 = new DefaultNodePath();
+        path2 = path2.add(1).add(1).add(2);
+        Either<Error, JungleTreeEditor> either2 = editor3.putAttribute(path2,addAttributeKey, ByteBuffer.wrap("value".getBytes()) );
+        Assert.assertFalse(either2.isA());
+        JungleTreeEditor editor4 = either2.b();
+        Either<Error, JungleTreeEditor> either3 = editor4.success();
+        Assert.assertFalse(either3.isA());
+
+        TreeNode newTreeRoot = tree.getRootNode();
+        ParentIndex newTreeParentIndex = tree.getParentIndex();
+        iterator = new JungleNodeIterator(newTreeRoot);
+        Assert.assertTrue(iterator.hasNext());
+        node = iterator.next();
+        Assert.assertEquals(newTreeRoot,node);
+        while(iterator.hasNext()){
+            TreeNode child = iterator.next();
+            Optional<TreeNode> parentOp = newTreeParentIndex.get(child);
+            Assert.assertTrue(parentOp.isPresent());
+            System.out.println(parentOp.get());
+        }
+
+        List<TreeNode> deletedNodeList = new LinkedList<>();
+        deletedNodeList = getDeletedNodeList(deletedNodeList,oldTreeRoot,path);
+        deletedNodeList = getDeletedNodeList(deletedNodeList,oldTreeRoot,path2);
+
+        for (TreeNode deletedNode : deletedNodeList) {
+            Optional<TreeNode> optional = newTreeParentIndex.get(deletedNode);
+            Assert.assertFalse(optional.isPresent());
+        }
+    }
+
+    private List<TreeNode> getDeletedNodeList(List<TreeNode> list, TreeNode oldTreeRoot, NodePath path) {
+        TreeNode node = oldTreeRoot;
+        for (Integer i : path.pop().right()) {
+            Children children = node.getChildren();
+            Either<Error, TreeNode> either = children.at(i);
+            Assert.assertFalse(either.isA());
+            node = either.b();
+            list.add(node);
+        }
+        return list;
+    }
+
+
+}
--- a/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/index/parentIndexTest.java	Tue Dec 20 20:09:56 2016 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-package jp.ac.u_ryukyu.ie.cr.jungle.index;
-
-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.transaction.node.TreeNode;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
-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 junit.framework.Assert;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-/**
- * Created by e115731 on 15/05/06.
- */
-public class parentIndexTest {
-    @Test
-    public void parentIndex() {
-        Jungle jungle = new DefaultJungle(null, "hogehoge",new DefaultTraverser());
-        jungle.createNewTree("tree");
-        JungleTree tree = jungle.getTreeByName("tree");
-        JungleTreeEditor editor = tree.getJungleTreeEditor();
-
-        DefaultNodePath path = new DefaultNodePath();
-        for (int count = 0; count < 100; count++) {
-            editor = editor.addNewChildAt(path, 0).b();
-            path = path.add(0);
-            editor = editor.putAttribute(path, "KEY", ByteBuffer.wrap(("data" + count).getBytes())).b();
-        }
-
-        Either<Error, JungleTreeEditor> either = editor.success();
-        Assert.assertTrue(either.isB());
-        TreeNode node = tree.getNodeOfPath(path).b();
-        ParentIndex parentIndex = tree.getParentIndex();
-        for (int count = 99; count >= 0; count--) {
-            String attribute = node.getAttributes().getString("KEY");
-            Assert.assertEquals(attribute, "data" + count);
-            node = parentIndex.get(node).get();
-        }
-    }
-}
--- a/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/traverse/InterfaceTraverserTest.java	Tue Dec 20 20:09:56 2016 +0900
+++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/traverse/InterfaceTraverserTest.java	Fri Dec 30 03:55:55 2016 +0900
@@ -3,36 +3,32 @@
 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.persistent.NullJournal;
-import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.NodePath;
 import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath;
+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.Default.DefaultTreeNode;
-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.traverser.InterfaceTraverser;
 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 junit.framework.Assert;
 import org.junit.Test;
 
-import java.nio.ByteBuffer;
 import java.util.Iterator;
 
+import static jp.ac.u_ryukyu.ie.cr.jungle.CreateTreeMethod.createTree;
+
 /**
  * Created by e115731 on 15/08/11.
  */
 public class InterfaceTraverserTest {
+    public static String key = "KEY";
+    public static String indexKey = "INDEXKEY";
     @Test
     public void InterfaseTraverserTest() {
         Jungle jungle = new DefaultJungle(new NullJournal(), "hoge", new DefaultTraverser());
         jungle.createNewTree("TestTree");
         JungleTree tree = jungle.getTreeByName("TestTree");
         JungleTreeEditor editor = tree.getJungleTreeEditor();
-        editor = createTree(editor, 0, 3, new DefaultNodePath());
-        Either<Error, JungleTreeEditor> either = editor.success();
-        if (either.isA())
-            Assert.fail();
+        editor = createTree(editor,key,indexKey, 3, new DefaultNodePath());
         InterfaceTraverser traverser = tree.getTraverser(true);
 
         {
@@ -83,34 +79,4 @@
             Assert.assertFalse(iterator.hasNext());
         }
     }
-
-    public static String key = "KEY";
-    public static String indexKey = "INDEXKEY";
-    public static DefaultTreeNode factory = new DefaultTreeNode();
-
-    public JungleTreeEditor createTree(JungleTreeEditor editor, int _curY, int _maxHeight, NodePath path) {
-
-        if (_curY == _maxHeight) {
-            return editor;
-        }
-        for (int i = 0; i < 3; i++) {
-
-            Either<Error, JungleTreeEditor> either = editor.addNewChildAt(path, i);
-            if (either.isA())
-                Assert.fail();
-            editor = either.b();
-            String value = path.add(i).toString();
-            either = editor.putAttribute(path.add(i), key, ByteBuffer.wrap(value.getBytes()));
-            if (either.isA())
-                Assert.fail();
-            editor = either.b();
-            either = editor.putAttribute(path.add(i), indexKey, ByteBuffer.wrap(value.getBytes()));
-            if (either.isA())
-                Assert.fail();
-            editor = either.b();
-            editor = createTree(editor, _curY + 1, _maxHeight, path.add(i));
-        }
-        return editor;
-    }
-
 }