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

net.amygdalum.util.text.linkeddawg.CharArrayNode Maven / Gradle / Ivy

The newest version!
package net.amygdalum.util.text.linkeddawg;

import net.amygdalum.util.text.CharNode;
import net.amygdalum.util.text.NodeResolver;

public class CharArrayNode implements CharNode {

	private static final int MAX_SIZE = 128;

	private int mask;
	private char[] chars;
	private CharNode[] nodes;
	private char[] alts;
	private T attached;

	private CharArrayNode(int mask, char[] chars, CharNode[] nodes, char[] alts, T attached) {
		this.mask = mask;
		this.chars = chars;
		this.nodes = nodes;
		this.alts = alts;
		this.attached = attached;
	}

	public static  CharArrayNode buildNodeFrom(CharNode node, NodeResolver> resolver) {
		int minsize = minimumSize(node.getAlternativesSize());
		if (minsize > MAX_SIZE) {
			return null;
		}
		char[] alts = node.getAlternatives();
		int size = computeArraySize(minsize, alts);
		if (size < 0) {
			return null;
		}
		T attached = node.getAttached();
		int mask = size - 1;

		char[] chars = new char[size];
		@SuppressWarnings("unchecked")
		CharNode[] nodes = new CharNode[size];
		for (char c : alts) {
			int index = ((int) c) & mask;
			chars[index] = c;
			nodes[index] = resolver.resolve(node.nextNode(c));
		}

		return new CharArrayNode(mask, chars, nodes, alts, attached);
	}

	private static  int computeArraySize(int minsize, char[] alternatives) {
		nextMask: for (int size = minsize; size <= MAX_SIZE; size <<= 1) {
			boolean[] collision = new boolean[size];
			int mask = size - 1;
			for (char c : alternatives) {
				int index = ((int) c) & mask;
				if (collision[index]) {
					continue nextMask;
				} else {
					collision[index] = true;
				}
			}
			return size;
		}
		return -1;
	}

	private static int minimumSize(int nextSize) {
		int minimumSize = 1;
		while (minimumSize < nextSize) {
			minimumSize <<= 1;
		}
		return minimumSize;
	}

	@Override
	public CharNode nextNode(char c) {
		if (nodes.length == 0) {
			return null;
		}
		int index = ((int) c) & mask;
		if (chars[index] != c) {
			return null;
		} else {
			return nodes[index];
		}
	}

	@Override
	public char[] getAlternatives() {
		return alts;
	}
	
	@Override
	public int getAlternativesSize() {
		return alts.length;
	}

	@Override
	public T getAttached() {
		return attached;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy