Mercurial > hg > Members > shoshi > jungle > jungle-core
view src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/node/redBlackTree/BlackTreeNode.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 BlackTreeNode extends ColorlessTreeNode { public BlackTreeNode(ColorlessTreeNode node) { this(node.getAttrs(), node.key(), node.value(), node.left(), node.right()); } public BlackTreeNode(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 BlackTreeNode(newAttrs, insertKey, insertValue, left, right); } @Override public TreeNode createNewNode() { return null;//new BlackTreeNode(); } @Override protected RebuildNode deleteNode() { ColorlessTreeNode emptyNode = new EmptyTreeNode(value()); return new RebuildNode(true, emptyNode); } 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 false; } @Override public boolean empty() { return false; } @Override public Rotate checkRotate(Rotate side) { return Rotate.N; } @Override protected ColorlessTreeNode insBalance() { Rotate spin = left().checkRotate(Rotate.L); if (spin == Rotate.R) { ColorlessTreeNode newLeftChild = new BlackTreeNode(left().left().getAttrs(), left().left().key(), left().left().value(), left().left().left(), left().left().right()); ColorlessTreeNode newRightChild = new BlackTreeNode(getAttrs(), key(), value(), left().right(), right()); return new RedTreeNode(left().getAttrs(), left().key(), left().value(), newLeftChild, newRightChild); } else if (spin == Rotate.LR) { ColorlessTreeNode newLeftChild = new BlackTreeNode(left().getAttrs(), left().key(), left().value(), left().left(), left().right().left()); ColorlessTreeNode newRightChild = new BlackTreeNode(getAttrs(), key(), value(), left().right().right(), right()); return new RedTreeNode(left().right().getAttrs(), left().right().key(), left().right().value(), newLeftChild, newRightChild); } spin = right().checkRotate(Rotate.R); if (spin == Rotate.L) { ColorlessTreeNode newLeftChild = new BlackTreeNode(getAttrs(), key(), value(), left(), right().left()); ColorlessTreeNode newRightChild = new BlackTreeNode(right().right().getAttrs(), right().right().key(), right().right().value(), right().right().left(), right().right().right()); return new RedTreeNode(right().getAttrs(), right().key(), right().value(), newLeftChild, newRightChild); } else if (spin == Rotate.RL) { ColorlessTreeNode newLeftChild = new BlackTreeNode(getAttrs(), key(), value(), left(), right().left().left()); ColorlessTreeNode newRightChild = new BlackTreeNode(right().getAttrs(), right().key(), right().value(), right().left().right(), right().right()); return new RedTreeNode(right().left().getAttrs(), right().left().key(), right().left().value(), newLeftChild, newRightChild); } return this; } @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();//黒が1つ減るので木のバランスを取る } else if (!this.left().empty() && this.right().empty()) { //左の部分木を昇格させる newNode = createNode(left().getAttrs(), left().key(), left().value(), left().left(), left().right()); if (!this.left().isRed()) //昇格させる木のrootが黒だったらバランスを取る return new RebuildNode(true, newNode); return new RebuildNode(false, newNode); } else if (this.left().empty() && !this.right().empty()) { //右の部分木を昇格させる newNode = createNode(right().getAttrs(), right().key(), right().value(), right().left(), right().right()); if (!this.right().isRed()) //昇格させる木のrootが黒だったらバランスを取る return new RebuildNode(true, newNode); return new RebuildNode(false, newNode); } else {//子ノードが左右にある場合 二回目はここには入らない //左の部分木の最大の値を持つNodeと自身を置き換える ColorlessTreeNode cur = this.left(); while (!cur.right().empty()) { //左の部分期の最大値を持つNodeを取得する cur = cur.right(); } if (!this.left().right().empty()) { //左の部分木が右の子を持っているか RebuildNode leftSubTreeNodeRebuildNode = this.left().deleteSubTreeMaxNode(null, Rotate.L);//最大値を削除した左の部分木を返す。rootはthisと同じ。 if (leftSubTreeNodeRebuildNode.rebuild()) { ColorlessTreeNode leftSubTreeNode = leftSubTreeNodeRebuildNode.getNode(); ColorlessTreeNode newParent = createNode(cur.getAttrs(), cur.key(), cur.value(), leftSubTreeNode, this.right()); return leftSubTreeNode.deleteBalance(newParent); } ColorlessTreeNode leftSubTreeNode = leftSubTreeNodeRebuildNode.getNode(); newNode = createNode(cur.getAttrs(), cur.key(), cur.value(), leftSubTreeNode, this.right()); //rootをcurと入れ替えることでNodeの削除は完了する 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(this.left().getAttrs(), this.left().key(), this.left().value(), leftSubTreeNode, this.right()); return new RebuildNode(false, newNode); } } } }