package com.googlecode.gaal.suffix.impl;
import com.googlecode.gaal.data.api.IntSequence;
import com.googlecode.gaal.data.impl.ArraySequence;
import com.googlecode.gaal.suffix.algorithm.api.LcpTableBuilder;
import com.googlecode.gaal.suffix.algorithm.api.SuffixTableBuilder;
import com.googlecode.gaal.suffix.api.IntervalTree;
import com.googlecode.gaal.suffix.api.IntervalTree.Interval;;
public abstract class AbstractIntervalTree<T extends Interval> extends SuffixArrayBase implements IntervalTree<T> {
public AbstractIntervalTree(IntSequence sequence, int alphabetSize, int[] suffixTable, int[] lcpTable) {
super(sequence, alphabetSize, suffixTable, lcpTable);
}
public AbstractIntervalTree(IntSequence sequence, int alphabetSize, SuffixTableBuilder suffixTableBuilder,
LcpTableBuilder lcpTableBuilder) {
super(sequence, alphabetSize, suffixTableBuilder, lcpTableBuilder);
}
protected abstract class AbstractInterval implements Interval {
protected final int left;
protected final int right;
protected AbstractInterval(int left, int right) {
this.left = left;
this.right = right;
}
@Override
public int left() {
return left;
}
@Override
public int right() {
return right;
}
@Override
public int size() {
return right - left + 1;
}
@Override
public IntSequence indices() {
return new ArraySequence(suffixTable, left, right + 1);
}
@Override
public IntSequence label() {
return label(0);
}
@Override
public IntSequence edgeLabel(Interval parent) {
return label(parent.lcp());
}
private IntSequence label(int offset) {
int start = suffixTable[left];
if (isTerminal())
return sequence.subSequence(start + offset, sequence.size());
else
return sequence.subSequence(start + offset, start + lcp());
}
@Override
public boolean isTerminal() {
return right == left;
}
@Override
public String toString() {
return String.format("%d-%d:%d", left, right, lcp());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + left;
result = prime * result + right;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("unchecked")
AbstractInterval other = (AbstractInterval) obj;
if (lcp() != other.lcp())
return false;
if (left != other.left)
return false;
if (right != other.right)
return false;
return true;
}
}
}