Add comments, rename variables, remove unused lookahead

This commit is contained in:
Douglas Lovell 2017-10-13 20:47:21 -03:00
parent b11c655ccf
commit 82d36386fd
6 changed files with 65 additions and 44 deletions

View File

@ -21,10 +21,19 @@ package org.ahocorasick.trie;
*/ */
class CharacterTransition extends Transition<Character> { class CharacterTransition extends Transition<Character> {
/**
* Create a character transition from a position in the source string
* @param c character to match
* @param start positon of character in source string
*/
public CharacterTransition(Character c, int start) { public CharacterTransition(Character c, int start) {
super(c, start, 1); super(c, start, 1);
} }
/**
* Create a character transition without regard for position
* @param c character to match
*/
public CharacterTransition(Character c) { public CharacterTransition(Character c) {
this(c, 0); this(c, 0);
} }

View File

@ -16,13 +16,20 @@
package org.ahocorasick.trie; package org.ahocorasick.trie;
/** /**
* Keyword encapsulates part of a potential match along with the count
* of prior source tokens consumed to create the potential match.
* *
* @author doug.lovell * @author doug.lovell
*/ */
public class Keyword implements Comparable { public class Keyword implements Comparable {
private final String text; private final String text;
private int depth; private int depth;
/**
* Create portion of potential match
* @param text content that matches
* @param depth count of prior source tokens that comprise the match
*/
public Keyword(String text, int depth) { public Keyword(String text, int depth) {
this.text = text; this.text = text;
this.depth = depth; this.depth = depth;
@ -37,7 +44,10 @@ public class Keyword implements Comparable {
} }
public String toString() { public String toString() {
return "Keyword '" + text + "' at depth " + depth; final String t = getText();
final int d = getDepth();
return "Keyword '" + t + "' at depth " + d;
} }
@Override @Override

View File

@ -27,7 +27,7 @@ import java.util.*;
*/ */
public class State { public class State {
/** effective the size of the keyword */ /** effectively the size of the keyword */
private final int depth; private final int depth;
/** only used for the root state to refer to itself in case no matches have been found */ /** only used for the root state to refer to itself in case no matches have been found */
@ -54,27 +54,27 @@ public class State {
this.rootState = depth == 0 ? this : null; this.rootState = depth == 0 ? this : null;
} }
private State nextState(Transition t, boolean ignoreRootState) { private State nextState(Transition transition, boolean ignoreRootState) {
State nextState = this.success.get(t); State nextState = this.success.get(transition);
if (!ignoreRootState && nextState == null && this.rootState != null) { if (!ignoreRootState && nextState == null && this.rootState != null) {
nextState = this.rootState; nextState = this.rootState;
} }
return nextState; return nextState;
} }
public State nextState(Transition t) { public State nextState(Transition transition) {
return nextState(t, false); return nextState(transition, false);
} }
public State nextStateIgnoreRootState(Transition t) { public State nextStateIgnoreRootState(Transition transition) {
return nextState(t, true); return nextState(transition, true);
} }
public State addState(Transition t) { public State addState(Transition transition) {
State nextState = nextStateIgnoreRootState(t); State nextState = nextStateIgnoreRootState(transition);
if (nextState == null) { if (nextState == null) {
nextState = new State(this.depth+1); nextState = new State(this.depth+1);
this.success.put(t, nextState); this.success.put(transition, nextState);
} }
return nextState; return nextState;
} }
@ -97,7 +97,7 @@ public class State {
} }
public void addEmitString(String key) { public void addEmitString(String key) {
addEmit(new Keyword(key, depth)); addEmit(new Keyword(key, getDepth()));
} }
public Collection<Keyword> emit() { public Collection<Keyword> emit() {

View File

@ -44,8 +44,10 @@ public class Transition<T> {
@Override @Override
public String toString() { public String toString() {
return "Transition on '" + token + "' start: " + start + final int s = getStart();
", length: " + length; final int len = getLength();
return "Transition on '" + token + "' start: " + s + ", length: " + len;
} }
@Override @Override

View File

@ -81,9 +81,8 @@ public class Trie {
} }
private class TokenStream { private class TokenStream {
private final KeywordTokenizer kwt; private final KeywordTokenizer tokenizer;
private final StringBuilder input; private final StringBuilder input;
private Transition lookahead;
public TokenStream(CharSequence text) { public TokenStream(CharSequence text) {
input = new StringBuilder(text.length()); input = new StringBuilder(text.length());
@ -93,23 +92,15 @@ public class Trie {
Character.toLowerCase(ch) : ch); Character.toLowerCase(ch) : ch);
} }
if (trieConfig.isOnlyWholeWords()) { if (trieConfig.isOnlyWholeWords()) {
kwt = new WordTokenizer(input); tokenizer = new WordTokenizer(input);
} }
else { else {
kwt = new CharacterTokenizer(input); tokenizer = new CharacterTokenizer(input);
} }
lookahead = null;
} }
public Transition nextTransition() { public Transition nextTransition() {
Transition next = lookahead; return tokenizer.nextTransition();
if (next == null) {
next = kwt.nextTransition();
}
else {
lookahead = null;
}
return next;
} }
public String input() { public String input() {
@ -123,13 +114,13 @@ public class Trie {
return; return;
} }
State currentState = this.rootState; State currentState = this.rootState;
TokenStream tknz = new TokenStream(keyword); TokenStream tokenStream = new TokenStream(keyword);
Transition tn = tknz.nextTransition(); Transition transition = tokenStream.nextTransition();
while (tn != null) { while (transition != null) {
currentState = currentState.addState(tn); currentState = currentState.addState(transition);
tn = tknz.nextTransition(); transition = tokenStream.nextTransition();
} }
currentState.addEmitString(tknz.input()); currentState.addEmitString(tokenStream.input());
} }
public Collection<Token> tokenize(String text) { public Collection<Token> tokenize(String text) {
@ -167,25 +158,25 @@ public class Trie {
LinkedList<Transition> tknHistory = new LinkedList<>(); LinkedList<Transition> tknHistory = new LinkedList<>();
State currentState = this.rootState; State currentState = this.rootState;
Transition tn = tknz.nextTransition(); Transition nextTransition = tknz.nextTransition();
while (tn != null) { while (nextTransition != null) {
if (flushHandler.stop()) { if (flushHandler.stop()) {
return; return;
} }
tknHistory.add(tn); tknHistory.add(nextTransition);
currentState = getState(currentState, tn, flushHandler); currentState = getState(currentState, nextTransition, flushHandler);
Collection<Keyword> emits = currentState.emit(); Collection<Keyword> emits = currentState.emit();
int depth = currentState.getDepth(); int depth = currentState.getDepth();
while (depth < tknHistory.size()) { while (depth < tknHistory.size()) {
tknHistory.remove(); tknHistory.remove();
} }
int position = nextTransition.getStart() + nextTransition.getLength();
for (Keyword emit : emits) { for (Keyword emit : emits) {
int position = tn.getStart() + tn.getLength();
int start = tknHistory.get(depth - emit.getDepth()).getStart(); int start = tknHistory.get(depth - emit.getDepth()).getStart();
emitCandidateHolder.addCandidate( emitCandidateHolder.addCandidate(
new Emit(start, position - 1, emit.getText())); new Emit(start, position - 1, emit.getText()));
} }
tn = tknz.nextTransition(); nextTransition = tknz.nextTransition();
} }
flushHandler.flush(); flushHandler.flush();
} }

View File

@ -21,11 +21,20 @@ package org.ahocorasick.trie;
*/ */
public class WordTransition extends Transition<String> { public class WordTransition extends Transition<String> {
public WordTransition(String s, int start) { /**
super(s, start, s.length()); * Create a transition from a position in the source string
* @param word to match
* @param start position of first character within the source string
*/
public WordTransition(String word, int start) {
super(word, start, word.length());
} }
public WordTransition(String s) { /**
this(s, 0); * Create a transition without regard for position
* @param word to match
*/
public WordTransition(String word) {
this(word, 0);
} }
} }