package edu.uncc.cs.watsonsim.nlp;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.util.Iterator;
import com.carrotsearch.hppc.ByteArrayList;
import com.carrotsearch.hppc.IntArrayList;
/** An append-only, compact string stack. */
public class StringStack implements Iterable<String> {
/** start_byte[i] = x --> word i starts at block[x], ends at block[start_byte[i+1]]
* The last element is where the free space begins. */
IntArrayList start_byte = IntArrayList.from(0);
ByteArrayList block = new ByteArrayList();
/** Create a string stack from some existing strings */
public StringStack(String... xs) {
for (String x: xs)
add(x);
}
/** Create a string stack from some existing strings */
public StringStack(Iterable<String> xs) {
for (String x: xs)
add(x);
}
/** How many strings are inside? */
public int size() {
return start_byte.size() - 1;
}
/** Does it have at least one string? */
public boolean isEmpty() {
return size() == 0;
}
/** Does this contain string x? (O(n) - and expensive)*/
public boolean contains(String o) {
for (String x: this) {
if (x.equals(o)) return true;
}
return false;
}
/** Add a string */
public boolean add(String e) {
block.add(e.getBytes(UTF_8));
start_byte.add(block.size());
return true;
}
/** Remove all contents */
public void clear() {
start_byte.clear();
start_byte.add(0);
block.clear();
}
/** Get a string by index */
public String get(int index) {
if (0 <= index && index + 1 < start_byte.size()) {
int offset = start_byte.get(index);
int length = start_byte.get(index+1) - offset;
return new String(block.buffer, offset, length);
} else {
return null;
}
}
/** Find string x (O(n) - and expensive) */
public int indexOf(String o) {
int i = 0;
for (String x: this) {
if (x.equals(o)) return i;
else i++;
}
return -1;
}
/** Iterate a StringList */
public Iterator<String> iterator() {
return new StringListIterator(this);
}
private class StringListIterator implements Iterator<String> {
private int index = 0;
private final StringStack sl;
public StringListIterator(StringStack sl) {
this.sl = sl;
}
@Override
public boolean hasNext() {
return index < sl.size();
}
@Override
public String next() {
return sl.get(index++);
}
}
}