diff --git a/src/main/java/org/ahocorasick/trie/Trie.java b/src/main/java/org/ahocorasick/trie/Trie.java index e0734f7..502830a 100644 --- a/src/main/java/org/ahocorasick/trie/Trie.java +++ b/src/main/java/org/ahocorasick/trie/Trie.java @@ -48,6 +48,11 @@ public class Trie { return this; } + public Trie stopOnHit() { + this.trieConfig.setStopOnHit(true); + return this; + } + public void addKeyword(String keyword) { if (keyword == null || keyword.length() == 0) { return; @@ -116,7 +121,9 @@ public class Trie { character = Character.toLowerCase(character); } currentState = getState(currentState, character); - storeEmits(position, currentState, emitHandler); + if (storeEmits(position, currentState, emitHandler) && trieConfig.isStopOnHit()) { + return; + } } } @@ -183,13 +190,16 @@ public class Trie { } } - private void storeEmits(int position, State currentState, EmitHandler emitHandler) { + private boolean storeEmits(int position, State currentState, EmitHandler emitHandler) { + boolean emitted = false; Collection emits = currentState.emit(); if (emits != null && !emits.isEmpty()) { for (String emit : emits) { emitHandler.emit(new Emit(position - emit.length() + 1, position, emit)); + emitted = true; } } + return emitted; } } diff --git a/src/main/java/org/ahocorasick/trie/TrieConfig.java b/src/main/java/org/ahocorasick/trie/TrieConfig.java index 6fa05c7..2d29788 100644 --- a/src/main/java/org/ahocorasick/trie/TrieConfig.java +++ b/src/main/java/org/ahocorasick/trie/TrieConfig.java @@ -8,6 +8,12 @@ public class TrieConfig { private boolean caseInsensitive = false; + private boolean stopOnHit = false; + + public boolean isStopOnHit() { return stopOnHit; } + + public void setStopOnHit(boolean stopOnHit) { this.stopOnHit = stopOnHit; } + public boolean isAllowOverlaps() { return allowOverlaps; } diff --git a/src/test/java/org/ahocorasick/trie/TrieTest.java b/src/test/java/org/ahocorasick/trie/TrieTest.java index 1ed76ef..fec647a 100644 --- a/src/test/java/org/ahocorasick/trie/TrieTest.java +++ b/src/test/java/org/ahocorasick/trie/TrieTest.java @@ -41,6 +41,21 @@ public class TrieTest { checkEmit(iterator.next(), 0, 2, "bcd"); } + @Test + public void ushersTestAndStopOnHit() { + Trie trie = new Trie(); + trie.addKeyword("hers"); + trie.addKeyword("his"); + trie.addKeyword("she"); + trie.addKeyword("he"); + trie.stopOnHit(); + Collection emits = trie.parseText("ushers"); + assertEquals(2, emits.size()); // she @ 3, he @ 3, hers @ 5 + Iterator iterator = emits.iterator(); + checkEmit(iterator.next(), 2, 3, "he"); + checkEmit(iterator.next(), 1, 3, "she"); + } + @Test public void ushersTest() { Trie trie = new Trie();