Mercurial > hg > Members > tatsuki > bench > jungle-core
view src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/IndexJungleTreeEditor.java @ 149:feb2346ace19
refactor ParentIndex
author | one |
---|---|
date | Sat, 22 Nov 2014 12:08:35 +0900 |
parents | 371b6ddb78f2 |
children | d9fbddf77bf6 |
line wrap: on
line source
package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction; import java.nio.ByteBuffer; import java.util.Iterator; import fj.P2; import fj.data.List; import fj.data.TreeMap; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.JungleTreeEditor; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.NodePath; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.IndexTreeEditor; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.TreeNode; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.TreeNodeChildren; 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.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.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; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Pair; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.TreeMapOrd; import jp.ac.u_ryukyu.ie.cr.tatsuki.jungle.store.index.DefaultIndexEditor; import jp.ac.u_ryukyu.ie.cr.tatsuki.jungle.store.index.DeleteChildIndexEditor; import jp.ac.u_ryukyu.ie.cr.tatsuki.jungle.store.index.IndexEditor; import jp.ac.u_ryukyu.ie.cr.tatsuki.jungle.store.index.ParentIndex; public class IndexJungleTreeEditor implements JungleTreeEditor { private final TransactionManager txManager; private final TreeNode root; private final TreeNode oldRoot; private final IndexTreeEditor editor; private final TreeOperationLog log; private final TreeOperationLog tmpLog; private TreeMap<String, TreeMap<String, List<TreeNode>>> index; private ParentIndex parentIndex; public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex() { return index; } public IndexJungleTreeEditor(TreeNode _root, TreeNode oldRoot, TransactionManager _txManager, IndexTreeEditor treeEditor, TreeMap<String, TreeMap<String, List<TreeNode>>> index, ParentIndex parentIndex) { this(_root, oldRoot, _txManager, treeEditor, new DefaultTreeOperationLog(), new DefaultTreeOperationLog(), index, parentIndex); } public IndexJungleTreeEditor(TreeNode _root, TreeNode oldRoot, TransactionManager _txManager, IndexTreeEditor treeEditor, TreeOperationLog log, TreeMap<String, TreeMap<String, List<TreeNode>>> index, ParentIndex parentIndex) { this(_root, oldRoot, _txManager, treeEditor, log, new DefaultTreeOperationLog(), index, parentIndex); } public IndexJungleTreeEditor(TreeNode newNode, TreeNode oldRoot, TransactionManager _txManager, IndexTreeEditor _editor, TreeOperationLog _log, TreeOperationLog tmpLog, TreeMap<String, TreeMap<String, List<TreeNode>>> index, ParentIndex parentIndex) { this.root = newNode; this.oldRoot = oldRoot; this.txManager = _txManager; this.editor = _editor; this.log = _log; this.index = index; this.parentIndex = parentIndex; this.tmpLog = tmpLog; } public Either<Error, IndexJungleTreeEditor> _edit(final NodePath _path, NodeEditor _e, IndexEditor indexEditor) { Either<Error, LoggingNode> either = editor.edit(root, _path, _e); if (either.isA()) { return DefaultEither.newA(either.a()); } LoggingNode newLogging = either.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<TreeOperation, NodeOperation>(newLog, converter); DefaultTreeOperationLog treeOperationLog = new DefaultTreeOperationLog(iterable, newLog.length()); TreeOperationLog newTmpLog = tmpLog.append(treeOperationLog); IndexJungleTreeEditor newIndexTreeEditor = new IndexJungleTreeEditor(newNode, oldRoot, txManager, this.editor, log, newTmpLog, index, parentIndex); return DefaultEither.newB(newIndexTreeEditor); } @Override public Either<Error, JungleTreeEditor> addNewChildAt(NodePath _path, int _pos) { AppendChildAt appendChildAt = new AppendChildAt(_pos); IndexEditor indexEditor = new DefaultIndexEditor(index); Either<Error, IndexJungleTreeEditor> either = _edit(_path, appendChildAt, indexEditor); Either<Error, JungleTreeEditor> newEither = DefaultEither.newB(either.b()); return newEither; } @Override public Either<Error, JungleTreeEditor> deleteChildAt(NodePath _path, int _pos) { DeleteChildAt deleteChildAt = new DeleteChildAt(_pos); DeleteChildIndexEditor indexEditor = new DeleteChildIndexEditor(_pos, index); Either<Error, IndexJungleTreeEditor> either = _edit(_path, deleteChildAt, indexEditor); JungleTreeEditor editor = either.b(); Either<Error, JungleTreeEditor> newEither = DefaultEither.newB(editor); return newEither; } @Override public Either<Error, JungleTreeEditor> putAttribute(NodePath _path, String _key, ByteBuffer _value) { PutAttribute putAttribute = new PutAttribute(_key, _value); IndexEditor indexEditor = new DefaultIndexEditor(index); Either<Error, IndexJungleTreeEditor> either = _edit(_path, putAttribute, indexEditor); JungleTreeEditor editor = either.b(); Either<Error, JungleTreeEditor> newEither = DefaultEither.newB(editor); return newEither; } @Override public Either<Error, JungleTreeEditor> deleteAttribute(NodePath _path, String _key) { DeleteAttribute deleteAttribute = new DeleteAttribute(_key); IndexEditor indexEditor = new DefaultIndexEditor(index); Either<Error, IndexJungleTreeEditor> either = _edit(_path, deleteAttribute, indexEditor); Either<Error, JungleTreeEditor> newEither = DefaultEither.newB(either.b()); return newEither; } @Override public Either<Error, JungleTreeEditor> edit(NodePath _path, NodeEditor _editor) { IndexEditor indexEditor = new DefaultIndexEditor(index); Either<Error, IndexJungleTreeEditor> either = _edit(_path, _editor, indexEditor); JungleTreeEditor editor = either.b(); Either<Error, JungleTreeEditor> newEither = DefaultEither.newB(editor); return newEither; } @Override public Either<Error, JungleTreeEditor> success() { ParentIndex newParentIndex = editParentIndex(tmpLog); TreeOperationLog newLog = log.append(tmpLog); Either<Error, TransactionManager> either = txManager.commit(root, newLog, index, newParentIndex); if (either.isA()) { return DefaultEither.newA(either.a()); } TransactionManager newTxManager = either.b(); JungleTreeEditor newTreeEditor = new IndexJungleTreeEditor(root, root, newTxManager, editor, index, parentIndex); return DefaultEither.newB(newTreeEditor); } private ParentIndex editParentIndex(TreeOperationLog tmpLog) { TreeMap<TreeNode, TreeNode> putParentNodeMap = TreeMap.empty(TreeMapOrd.treeNodeOrd); TreeMap<TreeNode, TreeNode> deleteParentNodeMap = TreeMap.empty(TreeMapOrd.treeNodeOrd); for (TreeOperation log : tmpLog) { NodePath targetNodePath = log.getNodePath(); putParentNodeMap = getTargetNode(TreeMap.empty(TreeMapOrd.treeNodeOrd), root, targetNodePath); deleteParentNodeMap = getTargetNode(TreeMap.empty(TreeMapOrd.treeNodeOrd), oldRoot, targetNodePath); System.out.println(log.getNodePath().toString()); } ParentIndex newParentIndex = parentIndex; if (!deleteParentNodeMap.isEmpty()) newParentIndex = deleteParentIndex(putParentNodeMap, newParentIndex); if (!putParentNodeMap.isEmpty()) newParentIndex = putParentIndex(putParentNodeMap,newParentIndex); return newParentIndex; } private ParentIndex deleteParentIndex(TreeMap<TreeNode, TreeNode> deleteParentNodeMap, ParentIndex editParentIndex) { Iterator<P2<TreeNode, TreeNode>> parentNodeIterator = deleteParentNodeMap.iterator(); ParentIndex newParentIndex = editParentIndex; for (; parentNodeIterator.hasNext();) { TreeNode parentNode = parentNodeIterator.next()._1(); TreeNodeChildren children = parentNode.getChildren(); Iterator<TreeNode> childrenIterator = children.iterator(); for (; childrenIterator.hasNext();) { TreeNode child = childrenIterator.next(); newParentIndex = newParentIndex.delete(child); } } return newParentIndex; } private ParentIndex putParentIndex(TreeMap<TreeNode, TreeNode> putParentNodeMap,ParentIndex editParentIndex) { Iterator<P2<TreeNode, TreeNode>> parentNodeIterator = putParentNodeMap.iterator(); ParentIndex newParentIndex = editParentIndex; for (; parentNodeIterator.hasNext();) { TreeNode parentNode = parentNodeIterator.next()._1(); TreeNodeChildren children = parentNode.getChildren(); Iterator<TreeNode> childrenIterator = children.iterator(); for (; childrenIterator.hasNext();) { TreeNode child = childrenIterator.next(); newParentIndex = newParentIndex.set(child, parentNode); } } return newParentIndex; } private TreeMap<TreeNode, TreeNode> getTargetNode(TreeMap<TreeNode, TreeNode> treeNodeMap, TreeNode node, NodePath path) { if (path.size() == 0) return treeNodeMap; Pair<Integer, NodePath> pathNode = path.pop(); if (pathNode.left() == -1) { TreeMap<TreeNode, TreeNode> newTreeNodeMap = treeNodeMap.set(node, node); return getTargetNode(newTreeNodeMap, node, pathNode.right()); } Either<Error, TreeNode> either = node.getChildren().at(pathNode.left()); if (either.isA()) return treeNodeMap; TreeNode child = either.b(); TreeMap<TreeNode, TreeNode> newTreeNodeMap = treeNodeMap.set(child, child); if (pathNode.right().size() == 0) return newTreeNodeMap; return getTargetNode(newTreeNodeMap, child, pathNode.right()); } @Override public String getID() { return txManager.getUUID(); } @Override public String getRevision() { return Long.toString(txManager.getRevision()); } @Override public TreeNode getRoot() { return root; } }