package org.arabidopsis.ahocorasick;
import java.util.Iterator;
private State<T> root;
private boolean prepared;
this.root = new State<T>(0);
this.prepared = false;
}
public void add(
byte[] keyword, T output) {
if (this.prepared)
throw new IllegalStateException(
"can't add keywords after prepare() is called");
State<T> lastState = this.root.extendAll(keyword);
lastState.addOutput(output);
}
this.prepareFailTransitions();
this.prepared = true;
}
public Iterator<SearchResult<T>>
search(
byte[] bytes) {
return new Searcher<T>(this, this.startSearch(bytes));
}
Queue<T> q = new Queue<T>();
for (int i = 0; i < 256; i++)
if (this.root.get((byte) i) != null) {
this.root.get((byte) i).setFail(this.root);
q.add(this.root.get((byte) i));
}
this.prepareRoot();
while (!q.isEmpty()) {
State<T> state = q.pop();
byte[] keys = state.keys();
for (int i = 0; i < keys.length; i++) {
State<T> r = state;
byte a = keys[i];
State<T> s = r.get(a);
q.add(s);
r = r.getFail();
while (r.get(a) == null)
r = r.getFail();
s.setFail(r.get(a));
s.getOutputs().addAll(r.get(a).getOutputs());
}
}
}
for (int i = 0; i < 256; i++)
if (this.root.get((byte) i) == null)
this.root.put((byte) i, this.root);
}
return this.root;
}
if (!this.prepared)
throw new IllegalStateException("can't start search until prepare()");
return continueSearch(new SearchResult<T>(this.root, bytes, 0));
}
byte[] bytes = lastResult.bytes;
State<T> state = lastResult.lastMatchedState;
for (int i = lastResult.lastIndex; i < bytes.length; i++) {
byte b = bytes[i];
while (state.get(b) == null)
state = state.getFail();
state = state.get(b);
if (state.getOutputs().size() > 0)
return new SearchResult<T>(state, bytes, i + 1);
}
return null;
}
}