view src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/editor/treeEditor/RedBlackTreeEditor.java @ 308:201cc75a9984

change Red Black Tree Edit Path Extends
author tatsuki
date Thu, 26 Jan 2017 15:23:25 +0900
parents 20fac8350822
children 474728dcfdb8
line wrap: on
line source

package jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.treeEditor;

import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
import jp.ac.u_ryukyu.ie.cr.jungle.store.logger.LoggingNode;
import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.NodePath;
import jp.ac.u_ryukyu.ie.cr.jungle.store.trasnformer.NodeEditor;
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.*;
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;

/**
 * Created by e115731 on 2017/01/02.
 */
public class RedBlackTreeEditor implements TreeEditor {

    private final Traverser traverser;

    public RedBlackTreeEditor(Traverser traverser) {
        this.traverser = traverser;
    }

    @Override
    public Either<Error, LoggingNode> edit(TreeNode root, NodePath path, NodeEditor editor) {
        if (path.get(0) == -2)
            return redBlackTreeNodeEdit(root, editor);
        Evaluator e = new RedBlackTreeEvaluator(path);
        Either<Error, Traversal> traverseEither = traverser.traverse(root, e);
        if (traverseEither.isA()) {
            return DefaultEither.newA(traverseEither.a());
        }
        Traversal traversal = traverseEither.b();
        TreeNode target = traversal.destination();
        Either<Error, LoggingNode> either = editor.edit(target);
        if (either.isA()) {
            return DefaultEither.newA(either.a());
        }
        LoggingNode newWrap = either.b();
        newWrap.setEditedNode(target);
        return clone(newWrap, traversal, editor);
    }



    private Either<Error, LoggingNode> redBlackTreeNodeEdit(TreeNode root, NodeEditor editor) {
        return editor.edit(root);
    }

    private Either<Error, LoggingNode> clone(LoggingNode newWrap, Traversal traversal, NodeEditor editor) {
        List<Direction<TreeNode>> path = new List<>();
        for (Direction<TreeNode> direction : traversal) {
            path = path.addLast(direction);
        }

        Direction<TreeNode> editedNodeDirection = path.head();

        // top
        int pos = editedNodeDirection.getPosition();
        TreeNode child = newWrap.getWrap();
        for (Direction<TreeNode> parentDirection : path.deleteHead()) {

            TreeNodeChildren chs = parentDirection.getTarget().getChildren();

            Either<Error, TreeNode> ret = chs.replaceNode(pos, child);
            if (ret.isA()) {
                return DefaultEither.newA(ret.a());
            }

            child = ret.b();
            pos = parentDirection.getPosition();
        }

        TreeNode newRoot = child;
        LoggingNode logNode = editor.wrap(newRoot, newWrap.getEditedNode(), newWrap.getOperationLog());
        return DefaultEither.newB(logNode);
    }
}