All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.sirix.index.art.Node4 Maven / Gradle / Ivy

package io.sirix.index.art;

class Node4 extends InnerNode {

	static final int NODE_SIZE = 4;

	// each array element would contain the partial byte key to match
	// if key matches then take up the same index from the child pointer array
	private final byte[] keys = new byte[NODE_SIZE];

	Node4() {
		super(NODE_SIZE);
	}

	Node4(Node16 node16) {
		super(node16, NODE_SIZE);
		assert node16.shouldShrink();
		byte[] keys = node16.getKeys();
		Node[] child = node16.getChildren();
		System.arraycopy(keys, 0, this.keys, 0, node16.noOfChildren);
		System.arraycopy(child, 0, this.children, 0, node16.noOfChildren);

		// update up links
		for (int i = 0; i < noOfChildren; i++) {
			replaceUplink(this, this.children[i]);
		}
	}

	@Override
	public Node findChild(byte partialKey) {
		partialKey = BinaryComparableUtils.unsigned(partialKey);
		// paper does simple loop over because it's a tiny array of size 4
		for (int i = 0; i < noOfChildren; i++) {
			if (keys[i] == partialKey) {
				return children[i];
			}
		}
		return null;
	}

	@Override
	public void addChild(byte partialKey, Node child) {
		assert !isFull();
		byte unsignedPartialKey = BinaryComparableUtils.unsigned(partialKey);
		// shift elements from this point to right by one place
		// noOfChildren here would never be == Node_SIZE (since we have isFull() check)
		int i = noOfChildren;
		for (; i > 0 && unsignedPartialKey < keys[i - 1]; i--) {
			keys[i] = keys[i - 1];
			this.children[i] = this.children[i - 1];
		}
		keys[i] = unsignedPartialKey;
		this.children[i] = child;
		noOfChildren++;
		createUplink(this, child, partialKey);
	}

	@Override
	public void replace(byte partialKey, Node newChild) {
		byte unsignedPartialKey = BinaryComparableUtils.unsigned(partialKey);

		int index = 0;
		for (; index < noOfChildren; index++) {
			if (keys[index] == unsignedPartialKey) {
				break;
			}
		}
		// replace will be called from in a state where you know partialKey entry surely exists
		assert index < noOfChildren : "Partial key does not exist";
		children[index] = newChild;
		createUplink(this, newChild, partialKey);
	}

	@Override
	public void removeChild(byte partialKey) {
		partialKey = BinaryComparableUtils.unsigned(partialKey);
		int index = 0;
		for (; index < noOfChildren; index++) {
			if (keys[index] == partialKey) {
				break;
			}
		}
		// if this fails, the question is, how could you reach the leaf node?
		// this node must've been your follow on pointer holding the partialKey
		assert index < noOfChildren : "Partial key does not exist";
		removeUplink(children[index]);
		for (int i = index; i < noOfChildren - 1; i++) {
			keys[i] = keys[i + 1];
			children[i] = children[i + 1];
		}
		children[noOfChildren - 1] = null;
		noOfChildren--;
	}

	@Override
	public InnerNode grow() {
		assert isFull();
		// grow from Node4 to Node16
		return new Node16(this);
	}

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

	@Override
	public InnerNode shrink() {
		throw new UnsupportedOperationException("Node4 is smallest node type");
	}

	@Override
	public Node first() {
		return children[0];
	}

	@Override
	public Node last() {
		return children[Math.max(0, noOfChildren - 1)];
	}

	@Override
	public Node ceil(byte partialKey){
		partialKey = BinaryComparableUtils.unsigned(partialKey);
		for (int i = 0; i < noOfChildren; i++) {
			if (keys[i] >= partialKey) {
				return children[i];
			}
		}
		return null;
	}

	@Override
	public Node greater(byte partialKey) {
		partialKey = BinaryComparableUtils.unsigned(partialKey);
		for (int i = 0; i < noOfChildren; i++) {
			if (keys[i] > partialKey) {
				return children[i];
			}
		}
		return null;
	}

	@Override
	public Node lesser(byte partialKey) {
		partialKey = BinaryComparableUtils.unsigned(partialKey);
		for (int i = noOfChildren - 1; i >= 0; i--) {
			if (keys[i] < partialKey) {
				return children[i];
			}
		}
		return null;
	}

	@Override
	public Node floor(byte partialKey) {
		partialKey = BinaryComparableUtils.unsigned(partialKey);
		for (int i = noOfChildren - 1; i >= 0; i--) {
			if (keys[i] <= partialKey) {
				return children[i];
			}
		}
		return null;
	}

	@Override
	public boolean isFull() {
		return noOfChildren == NODE_SIZE;
	}

	byte[] getKeys() {
		return keys;
	}

	byte getOnlyChildKey() {
		assert noOfChildren == 1;
		return BinaryComparableUtils.signed(keys[0]);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy