Skip to content

Commit 868eb7e

Browse files
author
mgeipel
committed
fixed #14
very minor improvement though more to come...
1 parent b0d8e86 commit 868eb7e

File tree

1 file changed

+150
-155
lines changed

1 file changed

+150
-155
lines changed

src/main/java/org/culturegraph/mf/util/tries/WildcardTrie.java

Lines changed: 150 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -13,158 +13,153 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.culturegraph.mf.util.tries;
17-
18-
import java.util.ArrayList;
19-
import java.util.Collections;
20-
import java.util.HashSet;
21-
import java.util.List;
22-
import java.util.Set;
23-
import java.util.regex.Pattern;
24-
25-
/**
26-
* A simple Trie, which accepts a trailing wildcard
27-
*
28-
* @author Markus Michael Geipel
29-
*
30-
* @param <P>
31-
* type of value stored
32-
*/
33-
public final class WildcardTrie<P> {
34-
public static final char STAR_WILDCARD = '*';
35-
public static final char Q_WILDCARD = '?';
36-
public static final String OR_STRING = "|";
37-
38-
private static final Pattern OR_PATTERN = Pattern.compile(OR_STRING, Pattern.LITERAL);
39-
private final Node<P> root = new Node<P>();
40-
41-
private Set<Node<P>> nodes = new HashSet<Node<P>>();
42-
private Set<Node<P>> nextNodes = new HashSet<Node<P>>();
43-
44-
/**
45-
* inserts keys into the try. Use '|' to concatenate. Use '*' (0,inf) and
46-
* '?' (1,1) to express wildcards.
47-
*
48-
* @param keys
49-
* @param value
50-
*/
51-
public void put(final String keys, final P value) {
52-
if (keys.contains(OR_STRING)) {
53-
final String[] keysSplit = OR_PATTERN.split(keys);
54-
for (String string : keysSplit) {
55-
simplyPut(string, value);
56-
}
57-
} else {
58-
simplyPut(keys, value);
59-
}
60-
}
61-
62-
private void simplyPut(final String key, final P value) {
63-
64-
final char[] keyChars = key.toCharArray();
65-
66-
final int length;
67-
length = keyChars.length;
68-
69-
70-
Node<P> node = root;
71-
Node<P> next = null;
72-
for (int i = 0; i < length; ++i) {
73-
next = node.getNext(keyChars[i]);
74-
if (next == null) {
75-
next = node.addNext(keyChars[i]);
76-
}
77-
node = next;
78-
}
79-
node.addValue(value);
80-
}
81-
82-
public List<P> get(final String key) {
83-
84-
final char[] keyChars = key.toCharArray();
85-
86-
nodes.add(root);
87-
88-
for (int i = 0; i < keyChars.length; ++i) {
89-
for (Node<P> node : nodes) {
90-
Node<P> temp;
91-
temp = node.getNext(keyChars[i]);
92-
if (temp != null) {
93-
nextNodes.add(temp);
94-
}
95-
temp = node.getNext(Q_WILDCARD);
96-
if (temp != null) {
97-
nextNodes.add(temp);
98-
}
99-
100-
temp = node.getNext(STAR_WILDCARD);
101-
if (temp != null) {
102-
nextNodes.add(temp);
103-
if (temp != node) {
104-
temp = temp.getNext(keyChars[i]);
105-
if (temp != null) {
106-
nextNodes.add(temp);
107-
}
108-
}
109-
}
110-
}
111-
nodes.clear();
112-
final Set<Node<P>> temp = nodes;
113-
nodes = nextNodes;
114-
nextNodes = temp;
115-
}
116-
117-
List<P> matches = Collections.emptyList();
118-
for (Node<P> node : nodes) {
119-
final List<P> values = node.getValues();
120-
if (!values.isEmpty()) {
121-
if (matches == Collections.emptyList()) {
122-
matches = new ArrayList<P>();
123-
}
124-
matches.addAll(values);
125-
}
126-
}
127-
nodes.clear();
128-
nextNodes.clear();
129-
return matches;
130-
}
131-
132-
/**
133-
*
134-
* @param <T>
135-
*/
136-
private final class Node<T> {
137-
138-
private List<T> values = Collections.emptyList();
139-
private final CharMap<Node<T>> links = new CharMap<Node<T>>();
140-
141-
protected Node() {
142-
// nothing to do
143-
}
144-
145-
public Node<T> addNext(final char key) {
146-
final Node<T> next = new Node<T>();
147-
links.put(key, next);
148-
if (key == STAR_WILDCARD) {
149-
next.links.put(STAR_WILDCARD, next);
150-
}
151-
152-
return next;
153-
}
154-
155-
public void addValue(final T value) {
156-
if (values == Collections.emptyList()) {
157-
values = new ArrayList<T>();
158-
}
159-
this.values.add(value);
160-
}
161-
162-
public List<T> getValues() {
163-
return values;
164-
}
165-
166-
public Node<T> getNext(final char key) {
167-
return links.get(key);
168-
}
169-
}
170-
}
16+
package org.culturegraph.mf.util.tries;
17+
18+
import java.util.ArrayList;
19+
import java.util.Collections;
20+
import java.util.HashSet;
21+
import java.util.List;
22+
import java.util.Set;
23+
import java.util.regex.Pattern;
24+
25+
/**
26+
* A simple Trie, which accepts a trailing wildcard
27+
*
28+
* @author Markus Michael Geipel
29+
*
30+
* @param <P>
31+
* type of value stored
32+
*/
33+
public final class WildcardTrie<P> {
34+
public static final char STAR_WILDCARD = '*';
35+
public static final char Q_WILDCARD = '?';
36+
public static final String OR_STRING = "|";
37+
38+
private static final Pattern OR_PATTERN = Pattern.compile(OR_STRING, Pattern.LITERAL);
39+
private final Node<P> root = new Node<P>();
40+
41+
private Set<Node<P>> nodes = new HashSet<Node<P>>();
42+
private Set<Node<P>> nextNodes = new HashSet<Node<P>>();
43+
44+
/**
45+
* inserts keys into the try. Use '|' to concatenate. Use '*' (0,inf) and
46+
* '?' (1,1) to express wildcards.
47+
*
48+
* @param keys
49+
* @param value
50+
*/
51+
public void put(final String keys, final P value) {
52+
if (keys.contains(OR_STRING)) {
53+
final String[] keysSplit = OR_PATTERN.split(keys);
54+
for (String string : keysSplit) {
55+
simplyPut(string, value);
56+
}
57+
} else {
58+
simplyPut(keys, value);
59+
}
60+
}
61+
62+
private void simplyPut(final String key, final P value) {
63+
64+
final int length = key.length();
65+
66+
Node<P> node = root;
67+
Node<P> next = null;
68+
for (int i = 0; i < length; ++i) {
69+
next = node.getNext(key.charAt(i));
70+
if (next == null) {
71+
next = node.addNext(key.charAt(i));
72+
}
73+
node = next;
74+
}
75+
node.addValue(value);
76+
}
77+
78+
public List<P> get(final String key) {
79+
80+
81+
nodes.add(root);
82+
final int length = key.length();
83+
for (int i = 0; i < length; ++i) {
84+
for (Node<P> node : nodes) {
85+
Node<P> temp;
86+
temp = node.getNext(key.charAt(i));
87+
if (temp != null) {
88+
nextNodes.add(temp);
89+
}
90+
temp = node.getNext(Q_WILDCARD);
91+
if (temp != null) {
92+
nextNodes.add(temp);
93+
}
94+
95+
temp = node.getNext(STAR_WILDCARD);
96+
if (temp != null) {
97+
nextNodes.add(temp);
98+
if (temp != node) {
99+
temp = temp.getNext(key.charAt(i));
100+
if (temp != null) {
101+
nextNodes.add(temp);
102+
}
103+
}
104+
}
105+
}
106+
nodes.clear();
107+
final Set<Node<P>> temp = nodes;
108+
nodes = nextNodes;
109+
nextNodes = temp;
110+
}
111+
112+
List<P> matches = Collections.emptyList();
113+
for (Node<P> node : nodes) {
114+
final List<P> values = node.getValues();
115+
if (!values.isEmpty()) {
116+
if (matches == Collections.emptyList()) {
117+
matches = new ArrayList<P>();
118+
}
119+
matches.addAll(values);
120+
}
121+
}
122+
nodes.clear();
123+
nextNodes.clear();
124+
return matches;
125+
}
126+
127+
/**
128+
*
129+
* @param <T>
130+
*/
131+
private final class Node<T> {
132+
133+
private List<T> values = Collections.emptyList();
134+
private final CharMap<Node<T>> links = new CharMap<Node<T>>();
135+
136+
protected Node() {
137+
// nothing to do
138+
}
139+
140+
public Node<T> addNext(final char key) {
141+
final Node<T> next = new Node<T>();
142+
links.put(key, next);
143+
if (key == STAR_WILDCARD) {
144+
next.links.put(STAR_WILDCARD, next);
145+
}
146+
147+
return next;
148+
}
149+
150+
public void addValue(final T value) {
151+
if (values == Collections.emptyList()) {
152+
values = new ArrayList<T>();
153+
}
154+
this.values.add(value);
155+
}
156+
157+
public List<T> getValues() {
158+
return values;
159+
}
160+
161+
public Node<T> getNext(final char key) {
162+
return links.get(key);
163+
}
164+
}
165+
}

0 commit comments

Comments
 (0)