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

rename Error package
author kono
date Sat, 08 Jul 2017 21:05:55 +0900
parents de68d37fec80
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.store.trasnformer.NodeEditorError;
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.util.DefaultEither;
import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
import jp.ac.u_ryukyu.ie.cr.jungle.util.jungleError.Error;

import java.nio.ByteBuffer;
import java.util.Iterator;

import static jp.ac.u_ryukyu.ie.cr.jungle.util.jungleError.JungleTreeError.INVALID_ARGUMENT;
import static jp.ac.u_ryukyu.ie.cr.jungle.util.jungleError.TreeEditorError.DELETE_VALUE_NOT_FOUND;

/**
 * Created by e115731 on 2017/01/03.
 */
public class RedBlackTreeNodeChildren implements TreeNodeChildren {

    private final ColorlessTreeNode node;
    private final TreeMap<String, ByteBuffer> attrs;

    public RedBlackTreeNodeChildren(ColorlessTreeNode node, TreeMap<String, ByteBuffer> attrs) {
        this.node = node;
        this.attrs = attrs;
    }

    private boolean boundaryCheck(int _pos) {
        int size = size();
        return size >= _pos && _pos >= 0;
    }


    @Override
    public Either<Error, TreeNode> addNewChildAndPutAttribtue(int pos, String key, ByteBuffer value) {
        ColorlessTreeNode newNode = node.addNewChild(key, value);
        if (newNode.isRed()) {
            ColorlessTreeNode newRoot = new BlackTreeNode(newNode);
            return DefaultEither.newB(newRoot);
        }
        return DefaultEither.newB(newNode);
    }

    @Override
    public Either<Error, TreeNode> matchingChildDeleteAt(String key, ByteBuffer value) {
        if (value == null)
            return DefaultEither.newA(INVALID_ARGUMENT);
        RebuildNode newNode = node.delete(key, value, null, Rotate.N);
        if (newNode == null)
            return DefaultEither.newA(DELETE_VALUE_NOT_FOUND); // 削除するノードが無かった場合
        ColorlessTreeNode root = newNode.getNode();
        if (root.empty())
            return DefaultEither.newB(new EmptyTreeNode());
        ColorlessTreeNode newRoot = new BlackTreeNode(root.getAttrs(), root.key(), root.value(), root.left(), root.right());
        return DefaultEither.newB(newRoot);
    }





    @Override
    public Either<Error, TreeNode> replaceNode(int pos, TreeNode replacement) {
        if (!boundaryCheck(pos)) {
            return DefaultEither.newA(NodeEditorError.INDEX_OUT_OF_BOUNDS);
        }
        ColorlessTreeNode newNode;
        if (pos == 0) { //左のノードを入れ替える場合
            newNode = node.createNode(attrs,node.key(),node.value(),(ColorlessTreeNode) replacement,node.right());
        } else {
            newNode = node.createNode(attrs,node.key(),node.value(),node.left(),(ColorlessTreeNode) replacement);
        }
        return DefaultEither.newB(newNode);
    }

    @Override
    public Either<Error, TreeNode> at(int pos) {
        if (!boundaryCheck(pos)) {
            return DefaultEither.newA(NodeEditorError.INDEX_OUT_OF_BOUNDS);
        }
        if (pos == 0) {
            if (!node.left().empty()) {
                ColorlessTreeNode child = node.left();
                return DefaultEither.newB(child);
            } else {
                ColorlessTreeNode child = node.right();
                return DefaultEither.newB(child);
            }
        } else {
            ColorlessTreeNode child = node.right();
            return DefaultEither.newB(child);
        }
    }

    @Override
    public int size() {
        int childrenCount = 0;
        if (!node.right().empty())
            childrenCount++;
        if (!node.left().empty())
            childrenCount++;
        return childrenCount;
    }

    @Override
    public Iterator<TreeNode> iterator() {
        return new Iterator<TreeNode>() {

            ColorlessTreeNode next = !node.left().empty() ? node.left() : node.right();

            @Override
            public boolean hasNext() {
                return !next.empty();
            }

            @Override
            public TreeNode next() {
                TreeNode current = next;
                if (next.equals(node.left())) {
                    next = node.right();
                    return current;
                }
                next = new EmptyTreeNode();
                return current;
            }

        };
    }

    // ---------------- 以下 赤黒木では使わない関数
    @Override
    public Either<Error, TreeNode> moveChild(int pos, String move) {
        return null;
    } //使わない


    /**
     *     赤黒木はPathを使ったノードの削除は行わない
     *     本気出したら実装できるから
     *     余裕ができたら実装しよう
     */
    @Override
    public Either<Error, TreeNode> deleteChildAt(int pos) {
        return null;
    }



    /**
     * 赤黒木ではノード単体の追加は行わない
     * なので下2つのaddNewChildAtは使われない
     * ここをなんとかしたかった
     */
    @Override
    public Either<Error, TreeNode> addNewChildAt(int pos) {
        return null;
    } //使わない

    @Override
    public Either<Error, TreeNode> addNewChildAt(int pos, TreeNode newChild) {
        return null;
    } //使わない

}