source: trunk/EventBenchCore/src/de/ugoe/cs/eventbench/models/TrieNode.java @ 106

Last change on this file since 106 was 106, checked in by sherbold, 13 years ago
  • code documentation
File size: 7.0 KB
RevLine 
[13]1package de.ugoe.cs.eventbench.models;
[1]2
[86]3import java.io.Serializable;
[1]4import java.security.InvalidParameterException;
[102]5import java.util.Collection;
[1]6import java.util.LinkedList;
7import java.util.List;
8
[13]9import de.ugoe.cs.eventbench.models.Trie.Edge;
10import de.ugoe.cs.eventbench.models.Trie.TrieVertex;
[1]11import de.ugoe.cs.util.StringTools;
[5]12import edu.uci.ics.jung.graph.DelegateTree;
[106]13import edu.uci.ics.jung.graph.Tree;
[1]14
[106]15/**
16 * <p>
17 * This class implements a node of a trie. Each node is associated with a symbol
18 * and has a counter. The counter marks the number of occurences of the sequence
19 * defined by the path from the root of the trie to this node.
20 * </p>
21 *
22 * @author Steffen Herbold
23 *
24 * @param <T>
25 *            Type of the symbols that are stored in the trie.
26 * @see Trie
27 */
28class TrieNode<T> implements Serializable {
[1]29
[86]30        /**
[106]31         * <p>
[86]32         * Id for object serialization.
[106]33         * </p>
[86]34         */
35        private static final long serialVersionUID = 1L;
[106]36
37        /**
38         * <p>
39         * Counter for the number of occurences of the sequence.
40         * </p>
41         */
[1]42        private int count;
[106]43
44        /**
45         * <p>
46         * Symbol associated with the node.
47         * </p>
48         */
[1]49        private final T symbol;
[106]50
51        /**
52         * <p>
53         * Child nodes of this node. If the node is a leaf this collection is empty.
54         * </p>
55         */
[102]56        private Collection<TrieNode<T>> children;
[106]57
58        /**
59         * <p>
60         * Constructor. Creates a new TrieNode without a symbol associated.<br>
61         * <b>This constructor should only be used to create the root node of the
62         * trie!</b>
63         * </p>
64         */
[6]65        TrieNode() {
66                this.symbol = null;
67                count = 0;
68                children = new LinkedList<TrieNode<T>>();
69        }
[106]70
71        /**
72         * <p>
73         * Constructor. Creates a new TrieNode. The symbol must not be null.
74         * </p>
75         *
76         * @param symbol
77         *            symbol associated with the trie node
78         */
[1]79        public TrieNode(T symbol) {
[106]80                if (symbol == null) {
81                        throw new InvalidParameterException(
82                                        "symbol must not be null. null is reserved for root node!");
[1]83                }
84                this.symbol = symbol;
85                count = 0;
86                children = new LinkedList<TrieNode<T>>();
87        }
88
[106]89        /**
90         * <p>
91         * Adds a given subsequence to the trie and increases the counters
92         * accordingly.
93         * </p>
94         *
95         * @param subsequence
96         *            subsequence whose counters are increased
97         * @see Trie#add(List)
98         */
[1]99        public void add(List<T> subsequence) {
[106]100                if (!subsequence.isEmpty()) {
101                        if (!symbol.equals(subsequence.get(0))) { // should be guaranteed by
102                                                                                                                // the
103                                                                                                                // recursion/TrieRoot!
[1]104                                throw new AssertionError("Invalid trie operation!");
105                        }
106                        count++;
107                        subsequence.remove(0);
[106]108                        if (!subsequence.isEmpty()) {
[1]109                                T nextSymbol = subsequence.get(0);
110                                getChildCreate(nextSymbol).add(subsequence);
111                        }
112                }
113        }
[106]114
115        /**
116         * <p>
117         * Returns the symbol associated with the node.
118         * </p>
119         *
120         * @return symbol associated with the node
121         */
[1]122        public T getSymbol() {
123                return symbol;
124        }
[106]125
126        /**
127         * <p>
128         * Returns the number of occurences of the sequence represented by the node.
129         * </p>
130         *
131         * @return number of occurences of the sequence represented by the node
132         */
[1]133        public int getCount() {
134                return count;
135        }
[106]136
137        /**
138         * <p>
139         * Returns the child of the node associated with the given symbol or creates
140         * it if it does not exist yet.
141         * </p>
142         *
143         * @param symbol
144         *            symbol whose node is required
145         * @return node associated with the symbol
146         * @see Trie#getChildCreate(Object)
147         */
148        protected TrieNode<T> getChildCreate(T symbol) {
[1]149                TrieNode<T> node = getChild(symbol);
[106]150                if (node == null) {
[1]151                        node = new TrieNode<T>(symbol);
152                        children.add(node);
153                }
154                return node;
155        }
[106]156
157        /**
158         * <p>
159         * Returns the child of the node associated with the given symbol or null if
160         * it does not exist.
161         * </p>
162         *
163         * @param symbol
164         *            symbol whose node is required
165         * @return node associated with the symbol; null if no such node exists
166         * @see Trie#getChild(Object)
167         */
[1]168        protected TrieNode<T> getChild(T symbol) {
[106]169                for (TrieNode<T> child : children) {
170                        if (child.getSymbol().equals(symbol)) {
[1]171                                return child;
172                        }
173                }
174                return null;
175        }
176
[106]177        /**
178         * <p>
179         * Searches the sub-trie of this trie node for a given sequence and returns
180         * the node associated with the sequence or null if no such node is found.
181         * </p>
182         *
183         * @param sequence
184         *            sequence that is searched for
185         * @return node associated with the sequence
186         * @see Trie#find(List)
187         */
[1]188        public TrieNode<T> find(List<T> subsequence) {
189                TrieNode<T> result = null;
[106]190                if (subsequence.isEmpty()) {
[1]191                        result = this;
192                } else {
193                        TrieNode<T> node = getChild(subsequence.get(0));
[106]194                        if (node != null) {
[1]195                                subsequence.remove(0);
196                                result = node.find(subsequence);
197                        }
198                }
199                return result;
200        }
[106]201
202        /**
203         * <p>
204         * Returns a collection of all symbols that follow a this node, i.e., the
205         * symbols associated with the children of this node.
206         * </p>
207         *
208         * @return symbols follow this node
209         * @see TrieNode#getFollowingSymbols()
210         */
[102]211        public Collection<T> getFollowingSymbols() {
212                Collection<T> followingSymbols = new LinkedList<T>();
[106]213                for (TrieNode<T> child : children) {
[1]214                        followingSymbols.add(child.getSymbol());
215                }
216                return followingSymbols;
217        }
[106]218
219        /**
220         * <p>
221         * The string representation of a node is {@code symbol.toString()#count}
222         * </p>
223         *
224         * @see java.lang.Object#toString()
225         */
[1]226        @Override
227        public String toString() {
[106]228                String str = symbol.toString() + " #" + count;
229                if (!children.isEmpty()) {
[1]230                        str += StringTools.ENDLINE + children.toString();
231                }
[106]232                return str;
[1]233        }
234
[106]235        /**
236         * <p>
237         * Generates a {@link Tree} represenation of the trie.
238         * </p>
239         *
240         * @param parent
241         *            parent vertex in the generated tree
242         * @param graph
243         *            complete tree
244         */
245        void getGraph(TrieVertex parent, DelegateTree<TrieVertex, Edge> graph) {
[6]246                TrieVertex currentVertex;
[106]247                if (symbol == null) {
[6]248                        currentVertex = new TrieVertex("root");
249                        graph.addVertex(currentVertex);
250                } else {
[106]251                        currentVertex = new TrieVertex(getSymbol().toString() + "#"
252                                        + getCount());
253                        graph.addChild(new Edge(), parent, currentVertex);
[6]254                }
[106]255                for (TrieNode<T> node : children) {
[6]256                        node.getGraph(currentVertex, graph);
[106]257                }
[5]258        }
[106]259
260        /**
261         * <p>
262         * Appends the current node to the dot representation of the trie.
263         * </p>
264         *
265         * @param stringBuilder
266         *            {@link StringBuilder} to which the dot representation is
267         *            appended
268         */
[30]269        void appendDotRepresentation(StringBuilder stringBuilder) {
270                String thisSaneId;
[106]271                if (symbol == null) {
[30]272                        thisSaneId = "root";
273                } else {
[106]274                        thisSaneId = symbol.toString().replace("\"", "\\\"")
275                                        .replaceAll("[\r\n]", "")
276                                        + "#" + count;
[30]277                }
[106]278                stringBuilder.append(" " + hashCode() + " [label=\"" + thisSaneId
279                                + "\"];" + StringTools.ENDLINE);
280                for (TrieNode<T> childNode : children) {
281                        stringBuilder.append(" " + hashCode() + " -> "
282                                        + childNode.hashCode() + ";" + StringTools.ENDLINE);
[30]283                }
[106]284                for (TrieNode<T> childNode : children) {
[30]285                        childNode.appendDotRepresentation(stringBuilder);
286                }
287        }
[1]288}
Note: See TracBrowser for help on using the repository browser.