changeset 53:ed890dcb673e

modified JungleTreeEditor
author Shoshi TAMAKI
date Fri, 08 Feb 2013 12:32:37 +0900
parents 8c6ff361b68a
children 650fe2a0dccc
files src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/JungleTreeEditor.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/persistent/ChangeList.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/ChangeSet.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/TreeNode.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/DefaultOperationLog.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/DefaultTreeOperationLog.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingChildren.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingNode.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingNodeHook.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/OperationLog.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/TreeOperationLog.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultChangeSet.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultJungleTreeEditor.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultTransactionManager.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultTreeNode.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/TransactionManager.java
diffstat 16 files changed, 175 insertions(+), 108 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/JungleTreeEditor.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/JungleTreeEditor.java	Fri Feb 08 12:32:37 2013 +0900
@@ -1,11 +1,11 @@
 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle;
 
 import java.nio.ByteBuffer;
-
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.NodePath;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.NodeEditor;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;
 
 public interface JungleTreeEditor
 {
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/persistent/ChangeList.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/persistent/ChangeList.java	Fri Feb 08 12:32:37 2013 +0900
@@ -1,7 +1,7 @@
 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.persistent;
 
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.Operation;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.TreeOperation;
 
-public interface ChangeList extends Iterable<Operation>
+public interface ChangeList extends Iterable<TreeOperation>
 {
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/ChangeSet.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/ChangeSet.java	Fri Feb 08 12:32:37 2013 +0900
@@ -2,7 +2,7 @@
 
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.persistent.ChangeList;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.Operation;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.TreeOperation;
 
 public interface ChangeSet
 {
@@ -13,5 +13,5 @@
 	public String uuid();
 	public long revision();
 	
-	public Iterable<Operation> getOperations();
+	public Iterable<TreeOperation> getOperations();
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/TreeNode.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/TreeNode.java	Fri Feb 08 12:32:37 2013 +0900
@@ -1,6 +1,7 @@
 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl;
 
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.AttributesContainer;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Parent;
 
 public interface TreeNode<T extends TreeNode<T>> extends Parent<T> , AttributesContainer
@@ -11,5 +12,7 @@
 	@Override
 	public TreeNodeAttributes<T> getAttributes();
 	
+	public Node getAsNode();
+	
 	public T createNewNode();
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/DefaultOperationLog.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/DefaultOperationLog.java	Fri Feb 08 12:32:37 2013 +0900
@@ -33,4 +33,10 @@
 	{
 		return new DefaultOperationLog(log.snoc(_op));
 	}
+
+	@Override
+	public int length()
+	{
+		return log.length();
+	}
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/DefaultTreeOperationLog.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/DefaultTreeOperationLog.java	Fri Feb 08 12:32:37 2013 +0900
@@ -2,6 +2,8 @@
 
 import java.util.Iterator;
 
+import com.google.common.collect.Iterables;
+
 import fj.data.List;
 
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.NodePath;
@@ -11,16 +13,19 @@
 
 public class DefaultTreeOperationLog implements TreeOperationLog
 {
-	private final List<TreeOperation> list;
+	private final Iterable<TreeOperation> list;
+	private final int size;
 	
 	public DefaultTreeOperationLog()
 	{
 		list = List.nil();
+		size = 0;
 	}
 	
-	private DefaultTreeOperationLog(List<TreeOperation> _list)
+	public DefaultTreeOperationLog(Iterable<TreeOperation> _list,int _size)
 	{
 		list = _list;
+		size = _size;
 	}
 
 	@Override
@@ -32,15 +37,26 @@
 	@Override
 	public TreeOperationLog add(NodePath _p, NodeOperation _op)
 	{
-		DefaultTreeOperation op = new DefaultTreeOperation(_p,_op);
-		List<TreeOperation> newList = list.snoc(op);
-		return new DefaultTreeOperationLog(newList);
+		TreeOperation op = new DefaultTreeOperation(_p,_op);
+		List<TreeOperation> newList = List.list(op);
+		Iterable<TreeOperation> concat = Iterables.concat(list,newList);
+		
+		return new DefaultTreeOperationLog(concat,size + 1);
+	}
+	
+	@Override
+	public TreeOperationLog append(TreeOperationLog _log)
+	{
+		int argumentLogSize = _log.length();
+		Iterable<TreeOperation> concat = Iterables.concat(list,_log);
+		
+		return new DefaultTreeOperationLog(concat,argumentLogSize + size);
 	}
 
 	@Override
 	public int length()
 	{
-		return list.length();
+		return size;
 	}
 
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingChildren.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingChildren.java	Fri Feb 08 12:32:37 2013 +0900
@@ -1,7 +1,6 @@
 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger;
 
 import java.util.Iterator;
-
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.AppendChildAtOperation;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.DeleteChildAtOperation;
@@ -11,7 +10,6 @@
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.DefaultEither;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.IterableConverter;
 
 public class LoggingChildren<T extends EditableNode<T>> implements EditableChildren<LoggingNode<T>>
 {
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingNode.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingNode.java	Fri Feb 08 12:32:37 2013 +0900
@@ -32,12 +32,12 @@
 		return new LoggingChildren<T>(wrap,log);
 	}
 	
-	public OperationLog getLogger()
+	public OperationLog getOperationLog()
 	{
 		return log;
 	}
 	
-	public T getWrapper()
+	public T getWrap()
 	{
 		return wrap;
 	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingNodeHook.java	Fri Feb 08 12:32:37 2013 +0900
@@ -0,0 +1,40 @@
+package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger;
+
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.EditableNode;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.NodeEditor;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.DefaultEither;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;
+
+public class LoggingNodeHook implements NodeEditor
+{
+	private OperationLog log;
+	private final NodeEditor editor;
+	
+	public LoggingNodeHook(NodeEditor _editor)
+	{
+		log = null;
+		editor = _editor;
+	}
+
+	@Override
+	public <T extends EditableNode<T>> Either<Error, T> edit(T _e)
+	{
+		LoggingNode<T> loggingNode = new LoggingNode<T>(_e);
+		Either<Error, LoggingNode<T>> either = editor.edit(loggingNode);
+		if(either.isA()){
+			return DefaultEither.newA(either.a());
+		}
+		
+		LoggingNode<T> newLoggingNode = either.b();
+		T newNode = newLoggingNode.getWrap();
+		log = newLoggingNode.getOperationLog();
+		
+		return DefaultEither.newB(newNode);
+	}
+	
+	public OperationLog getLog()
+	{
+		return log;
+	}
+}
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/OperationLog.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/OperationLog.java	Fri Feb 08 12:32:37 2013 +0900
@@ -6,4 +6,5 @@
 public interface OperationLog extends Iterable<NodeOperation>
 {
 	public OperationLog add(NodeOperation _op);
+	public int length();
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/TreeOperationLog.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/TreeOperationLog.java	Fri Feb 08 12:32:37 2013 +0900
@@ -7,5 +7,6 @@
 public interface TreeOperationLog extends Iterable<TreeOperation>
 {
 	public TreeOperationLog add(NodePath _p,NodeOperation _op);
+	public TreeOperationLog append(TreeOperationLog _log);
 	public int length();
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultChangeSet.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultChangeSet.java	Fri Feb 08 12:32:37 2013 +0900
@@ -3,19 +3,17 @@
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.persistent.ChangeList;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.ChangeSet;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultNode;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.DefaultLogger;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.Operation;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.TreeOperation;
 
 public class DefaultChangeSet implements ChangeSet
 {
-	private final DefaultNode root;
+	private final Node root;
 	private final ChangeSet previous;
 	private final ChangeList changeList;
 	private final String uuid;
 	private final long revision;
 	
-	public DefaultChangeSet(DefaultNode _node,ChangeSet _prev,ChangeList _log,String _uuid,long _revision)
+	public DefaultChangeSet(Node _node,ChangeSet _prev,ChangeList _log,String _uuid,long _revision)
 	{
 		root = _node;
 		previous = _prev;
@@ -25,7 +23,7 @@
 	}
 
 	@Override
-	public DefaultNode getRoot()
+	public Node getRoot()
 	{
 		return root;
 	}
@@ -55,7 +53,7 @@
 	}
 
 	@Override
-	public Iterable<Operation> getOperations()
+	public Iterable<TreeOperation> getOperations()
 	{
 		return changeList;
 	}
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultJungleTreeEditor.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultJungleTreeEditor.java	Fri Feb 08 12:32:37 2013 +0900
@@ -1,131 +1,128 @@
 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction;
 
 import java.nio.ByteBuffer;
+import java.util.Iterator;
 
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.JungleTree;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.JungleTreeEditor;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.NodePath;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.ClonableNode;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.TreeEditor;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultNode;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultTreeEditor;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.Logger;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.TreeNode;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.DefaultTreeOperationLog;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.LoggingNode;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.LoggingNodeHook;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.OperationLog;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.TreeOperationLog;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.DefaultTreeOperation;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.NodeOperation;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.TreeOperation;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.AppendChildAt;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.DeleteAttribute;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.DeleteChildAt;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.NodeEditor;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.PutAttribute;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.Traverser;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.DefaultEither;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.IterableConverter;
 
-public class DefaultJungleTreeEditor<T extends ClonableNode<T>> implements JungleTreeEditor
+public class DefaultJungleTreeEditor<T extends TreeNode<T>> implements JungleTreeEditor
 {
 	private final TransactionManager txManager;
 	private final T root;
-	private final DefaultTreeEditor editor;
+	private final TreeEditor editor;
 	private final Traverser traverser;
-	private final OperationLog log;
+	private final TreeOperationLog log;
 
-	public DefaultJungleTreeEditor(T _root,TransactionManager _txManager,Traverser _traverser)
+	public DefaultJungleTreeEditor(T _root,TransactionManager _txManager,Traverser _traverser,TreeEditor _editor)
+	{
+		this(_root,_txManager,_traverser,_editor,new DefaultTreeOperationLog());
+	}
+	
+	public DefaultJungleTreeEditor(T _root,TransactionManager _txManager,Traverser _traverser,TreeEditor _editor,TreeOperationLog _log)
 	{
 		root = _root;
 		txManager = _txManager;
-		editor = new DefaultTreeEditor(_traverser);
+		editor = _editor;
 		traverser = _traverser;
+		log = _log;
 	}
 	
-	public DefaultJungleTreeEditor(LoggingNode<ClonableDefaultNode> _loggingNode,TransactionManager _txManager,Traverser _traverser)
+	private Either<Error,JungleTreeEditor> _edit(final NodePath _path,NodeEditor _e)
 	{
-		root = _loggingNode.getWrapper().getWrapped();
-		txManager = _txManager;
-		editor = new DefaultTreeEditor<LoggingNode<ClonableDefaultNode>>(_loggingNode,_traverser);
-		traverser = _traverser;
-	}
-	
-	@Override
-	public Either<Error,JungleTreeEditor> appendChild(NodePath _path, int _pos)
-	{
-		AppendChildAt appendChildAt = new AppendChildAt(_pos);
-		Either<Error,T> either = editor.edit(root,_path,appendChildAt);
+		LoggingNodeHook hook = new LoggingNodeHook(_e);
+		Either<Error,T> either = editor.edit(root,_path,_e);
 		if(either.isA()){
 			return DefaultEither.newA(either.a());
 		}
 		
-		DefaultTreeEditor<LoggingNode<ClonableDefaultNode>> newTreeEditor = either.b();
-		DefaultNode newRoot = newTreeEditor.getRootNode().getWrapper().getWrapped();
+		T newNode = either.b();
+		OperationLog newLog = hook.getLog();
 		
-		return DefaultEither.newB(new DefaultJungleTreeEditor(newTreeEditor.getRootNode(),txManager,traverser));
-	}
-
-	@Override
-	public Either<Error,DefaultJungleTreeEditor> deleteChild(NodePath _path, int _pos)
-	{
-		Either<Error,DefaultTreeEditor<LoggingNode<ClonableDefaultNode>>> either = editor.deleteChild(_path,_pos);
-		if(either.isA()){
-			return DefaultEither.newA(either.a());
-		}
+		IterableConverter.Converter<TreeOperation,NodeOperation> converter = new IterableConverter.Converter<TreeOperation,NodeOperation>(){
+			@Override
+			public TreeOperation conv(NodeOperation _b){
+				return new DefaultTreeOperation(_path,_b);
+			}
+		};
 		
-		DefaultTreeEditor<LoggingNode<ClonableDefaultNode>> newTreeEditor = either.b();
-		DefaultNode newRoot = newTreeEditor.getRootNode().getWrapper().getWrapped();
+		Iterable<TreeOperation> iterable = new IterableConverter<TreeOperation,NodeOperation>(newLog,converter);
+		DefaultTreeOperationLog treeOperationLog = new DefaultTreeOperationLog(iterable,newLog.length());
+		TreeOperationLog newTreeOpLog = log.append(treeOperationLog);
 		
-		return DefaultEither.newB(new DefaultJungleTreeEditor(newTreeEditor.getRootNode(),txManager,traverser));
+		JungleTreeEditor newEditor = new DefaultJungleTreeEditor<T>(newNode,txManager,traverser,editor,newTreeOpLog);
+		return DefaultEither.newB(newEditor);
 	}
-
+	
 	@Override
-	public Either<Error,DefaultJungleTreeEditor> putAttribute(NodePath _path,String _key,ByteBuffer _value)
+	public Either<Error,JungleTreeEditor> addNewChildAt(NodePath _path, int _pos)
 	{
-		Either<Error,DefaultTreeEditor<LoggingNode<ClonableDefaultNode>>> either = editor.putAttribute(_path,_key,_value);
-		if(either.isA()){
-			return DefaultEither.newA(either.a());
-		}
-		
-		DefaultTreeEditor<LoggingNode<ClonableDefaultNode>> newTreeEditor = either.b();
-		DefaultNode newRoot = newTreeEditor.getRootNode().getWrapper().getWrapped();
-		
-		return DefaultEither.newB(new DefaultJungleTreeEditor(newTreeEditor.getRootNode(),txManager,traverser));
+		AppendChildAt appendChildAt = new AppendChildAt(_pos);
+		return _edit(_path,appendChildAt);
 	}
 
 	@Override
-	public Either<Error,DefaultJungleTreeEditor> deleteAttribute(NodePath _path, String _key)
+	public Either<Error,JungleTreeEditor> deleteChildAt(NodePath _path, int _pos)
 	{
-		Either<Error,DefaultTreeEditor<LoggingNode<ClonableDefaultNode>>> either = editor.deleteAttribute(_path,_key);
-		if(either.isA()){
-			return DefaultEither.newA(either.a());
-		}
-		
-		DefaultTreeEditor<LoggingNode<ClonableDefaultNode>> newTreeEditor = either.b();
-		DefaultNode newRoot = newTreeEditor.getRootNode().getWrapper().getWrapped();
-		
-		return DefaultEither.newB(new DefaultJungleTreeEditor(newRoot,txManager,traverser));
+		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,DefaultJungleTreeEditor> edit(NodePath _path,NodeEditor _transformer)
+	public Either<Error,JungleTreeEditor> deleteAttribute(NodePath _path, String _key)
 	{
-		Either<Error,DefaultTreeEditor<LoggingNode<ClonableDefaultNode>>> either = editor.edit(_path,_transformer);
-		if(either.isA()){
-			return DefaultEither.newA(either.a());
-		}
-		
-		DefaultTreeEditor<LoggingNode<ClonableDefaultNode>> newTreeEditor = either.b();
-		DefaultNode newRoot = newTreeEditor.getRootNode().getWrapper().getWrapped();
-		
-		return DefaultEither.newB(new DefaultJungleTreeEditor(newRoot,txManager,traverser));
+		DeleteAttribute deleteAttribute = new DeleteAttribute(_key);
+		return _edit(_path,deleteAttribute);
 	}
 
 	@Override
-	public Either<Error,DefaultJungleTreeEditor> success()
+	public Either<Error,JungleTreeEditor> edit(NodePath _path,NodeEditor _editor)
 	{
-		LoggingNode<ClonableDefaultNode> loggingNode = editor.getRootNode();
-		Logger log = loggingNode.getLogger();
-		DefaultNode newRoot = loggingNode.getWrapper().getWrapped();
-		
-		Either<Error,TransactionManager> either = txManager.commit(newRoot,log);
+		return _edit(_path,_editor);
+	}
+
+	@Override
+	public Either<Error,JungleTreeEditor> success()
+	{
+		Node node = root.getAsNode();
+		Either<Error,TransactionManager> either = txManager.commit(node,log);
 		if(either.isA()){
 			return DefaultEither.newA(either.a());
 		}
 		
 		TransactionManager newTxManager = either.b();
-		DefaultJungleTreeEditor newTreeEditor = new DefaultJungleTreeEditor(newRoot,newTxManager,traverser);
+		JungleTreeEditor newTreeEditor = new DefaultJungleTreeEditor<T>(root,newTxManager,traverser,editor);
 		
 		return DefaultEither.newB(newTreeEditor);
 	}
@@ -141,4 +138,10 @@
 	{
 		return Long.toString(txManager.getRevision());
 	}
+
+	@Override
+	public Node getRoot()
+	{
+		return null;
+	}
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultTransactionManager.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultTransactionManager.java	Fri Feb 08 12:32:37 2013 +0900
@@ -1,17 +1,12 @@
 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction;
 
 import java.util.Iterator;
-import java.util.concurrent.atomic.AtomicReference;
-
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.JungleTree;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.persistent.ChangeList;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.persistent.ChangeListWriter;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.persistent.Result;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.ChangeSet;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultNode;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.DefaultLogger;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.Logger;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.Operation;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.TreeOperationLog;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.TreeOperation;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction.AtomicReservableReference.Reservation;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.DefaultEither;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.DefaultError;
@@ -35,14 +30,14 @@
 	}
 	
 	@Override
-	public Either<Error,TransactionManager> commit(DefaultNode _newRoot,final Logger _log)
+	public Either<Error,TransactionManager> commit(Node _newRoot,final TreeOperationLog _log)
 	{
 		long currentRevision = tip.revision();
 		long nextRevision = currentRevision + 1;
 		
 		ChangeList list = new ChangeList(){
 			@Override
-			public Iterator<Operation> iterator(){
+			public Iterator<TreeOperation> iterator(){
 				return _log.iterator();
 			}
 		};
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultTreeNode.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/DefaultTreeNode.java	Fri Feb 08 12:32:37 2013 +0900
@@ -1,5 +1,6 @@
 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction;
 
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultNode;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.TreeNode;
 
@@ -39,4 +40,10 @@
 	{
 		return wrap;
 	}
+
+	@Override
+	public Node getAsNode()
+	{
+		return getWrap();
+	}
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/TransactionManager.java	Fri Feb 08 03:50:21 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/TransactionManager.java	Fri Feb 08 12:32:37 2013 +0900
@@ -1,14 +1,13 @@
 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction;
 
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultNode;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.Logger;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.OperationLog;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.TreeOperationLog;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;
 
 public interface TransactionManager
 {
-	public Either<Error,TransactionManager> commit(DefaultNode _newRoot,TreeOperationLog _log);
+	public Either<Error,TransactionManager> commit(Node _newRoot,TreeOperationLog _log);
 	public String getUUID();
 	public long getRevision();
 }