view src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/node/redBlackTree/RedTreeNode.java @ 329:2a0cb1f0ba4e

rename Error package
author kono
date Sat, 08 Jul 2017 21:05:55 +0900
parents 1f929fe9c153
children
line wrap: on
line source

package jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.redBlackTree;

import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.Rotate;
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.DefaultEither;
import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
import jp.ac.u_ryukyu.ie.cr.jungle.util.jungleError.Error;
import org.junit.Test;

import java.nio.ByteBuffer;

import static jp.ac.u_ryukyu.ie.cr.jungle.util.jungleError.TreeNodeError.NOT_USE_METHOD;

public class RedTreeNode extends ColorlessTreeNode {

    public RedTreeNode(String balanceKey, ByteBuffer value) {
        this(new TreeMap<>(), balanceKey, value, new EmptyTreeNode(), new EmptyTreeNode());
    }

    public RedTreeNode(TreeMap<String, ByteBuffer> _attrs, String balanceKey, ByteBuffer value, ColorlessTreeNode left, ColorlessTreeNode right) {
        super(_attrs, balanceKey, value, left, right);
    }

    @Override
    public ColorlessTreeNode createNode(TreeMap<String, ByteBuffer> newAttrs, String insertKey, ByteBuffer insertValue, ColorlessTreeNode left, ColorlessTreeNode right) {
        return new RedTreeNode(newAttrs, insertKey, insertValue, left, right);
    }

    @Override
    protected RebuildNode deleteNode() {
        ColorlessTreeNode emptyNode = new EmptyTreeNode(value());
        return new RebuildNode(false, emptyNode);
    }

    @Override
    public TreeNode createNewNode() {
        return null;//new BlackTreeNode();
    }

    public TreeNode clone() {
        return new BlackTreeNode(getAttrs(), key(), value(), left(), right());
    }

    @Override
    public Either<Error, TreeNode> appendRootNode() {
        return DefaultEither.newA(NOT_USE_METHOD);
    }

    @Override
    public int compareTo(TreeNode o) {
        return this.getHash() - o.getHash();
    }

    @Override
    public int getHash() {
        return value().hashCode();
    }

    @Override
    public boolean isRed() {
        return true;
    }

    @Override
    public boolean empty() {
        return false;
    }

    @Override
    protected ColorlessTreeNode insBalance() {
        return this;
    }

    @Override
    public Rotate checkRotate(Rotate side) {
        if (side == Rotate.L) {
            if (left().isRed())
                return Rotate.R;
            else if (right().isRed())
                return Rotate.LR;
            return Rotate.N;
        } else {
            if (left().isRed())
                return Rotate.RL;
            else if (right().isRed())
                return Rotate.L;
            return Rotate.N;
        }
    }


    @Override
    @Test
    public int checkDepth(int count, int minCount) { // test method
        count++;
        minCount = left().checkDepth(count, minCount);
        minCount = right().checkDepth(count, minCount);
        return minCount;
    }

    @Override
    protected RebuildNode replaceNode(ColorlessTreeNode parent) {
        ColorlessTreeNode newNode;
        if (this.left().empty() && this.right().empty()) { //自身を削除する
            return deleteNode();
        } else if (!this.left().empty() && this.right().empty()) { //左の部分木を昇格させる
            newNode = left().createNode(left().getAttrs(), left().key(), left().value(), left().left(), left().right());
            return new RebuildNode(false, newNode);
        } else if (this.left().empty() && !this.right().empty()) { //右の部分木を昇格させる
            newNode = right().createNode(right().getAttrs(), right().key(), right().value(), right().left(), right().right());
            return new RebuildNode(false, newNode);
        } else {//子ノードが左右にある場合
            //左の部分木の最大の値を持つNodeと自身を置き換える
            ColorlessTreeNode cur = this.left();

            while (!cur.right().empty()) {
                cur = cur.right();
            }
            if (!this.left().right().empty()) {
                RebuildNode leftSubTreeNodeRebuildNode = this.left().deleteSubTreeMaxNode(null, Rotate.L);
                if (leftSubTreeNodeRebuildNode.rebuild()) {
                    ColorlessTreeNode node = leftSubTreeNodeRebuildNode.getNode();
                    ColorlessTreeNode newParent = createNode(cur.getAttrs(), cur.key(), cur.value(), node, this.right());
                    return node.deleteBalance(newParent);
                }
                ColorlessTreeNode leftSubTreeNode = leftSubTreeNodeRebuildNode.getNode();
                newNode = createNode(cur.getAttrs(), cur.key(), cur.value(), leftSubTreeNode, this.right());
                return new RebuildNode(false, newNode);
            } else {
                RebuildNode leftSubTreeNodeRebuildNode = this.left().replaceNode(this);
                if (leftSubTreeNodeRebuildNode.rebuild()) {
                    ColorlessTreeNode node = leftSubTreeNodeRebuildNode.getNode();
                    ColorlessTreeNode newParent = createNode(this.left().getAttrs(), this.left().key(), this.left().value(), node, this.right());
                    return node.deleteBalance(newParent);
                }
                ColorlessTreeNode leftSubTreeNode = leftSubTreeNodeRebuildNode.getNode();
                newNode = createNode(cur.getAttrs(),cur.key(), cur.value(), leftSubTreeNode, this.right());
                return new RebuildNode(false, newNode);
            }

        }
    }

}