EMMA Coverage Report (generated Fri Nov 19 16:42:38 EST 2010)
[all classes][org.fgraph.steps]

COVERAGE SUMMARY FOR SOURCE FILE [Traversers.java]

nameclass, %method, %block, %line, %
Traversers.java100% (14/14)100% (62/62)100% (784/784)100% (170/170)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Traversers100% (1/1)100% (12/12)100% (95/95)100% (20/20)
Traversers (): void 100% (1/1)100% (3/3)100% (2/2)
breadthFirst (Object, Function, Function): Iterable 100% (1/1)100% (9/9)100% (2/2)
breadthFirstSteps (Object, Function, Function): Iterable 100% (1/1)100% (7/7)100% (1/1)
depthFirst (Object, Function, Function): Iterable 100% (1/1)100% (9/9)100% (2/2)
depthFirstSteps (Object, Function, Function): Iterable 100% (1/1)100% (7/7)100% (1/1)
distinct (Function, Function): StepFunction 100% (1/1)100% (6/6)100% (1/1)
postOrder (Object, Function, Function): Iterable 100% (1/1)100% (9/9)100% (2/2)
postOrderSteps (Object, Function, Function): Iterable 100% (1/1)100% (9/9)100% (2/2)
preOrder (Object, Function, Function): Iterable 100% (1/1)100% (9/9)100% (2/2)
preOrderSteps (Object, Function, Function): Iterable 100% (1/1)100% (9/9)100% (2/2)
priority (Object, Function, Comparator, Function): Iterable 100% (1/1)100% (10/10)100% (2/2)
prioritySteps (Object, Function, Comparator, Function): Iterable 100% (1/1)100% (8/8)100% (1/1)
     
class Traversers$BreadthFirstIterable100% (1/1)100% (3/3)100% (52/52)100% (8/8)
Traversers$BreadthFirstIterable (Object, Function, Function): void 100% (1/1)100% (10/10)100% (4/4)
stepIterator (Object): Iterator 100% (1/1)100% (20/20)100% (3/3)
toString (): String 100% (1/1)100% (22/22)100% (1/1)
     
class Traversers$BreadthFirstTraverser100% (1/1)100% (5/5)100% (99/99)100% (26/26)
Traversers$BreadthFirstTraverser (Object, Function): void 100% (1/1)100% (21/21)100% (7/7)
hasNext (): boolean 100% (1/1)100% (34/34)100% (8/8)
next (): PrunableStep 100% (1/1)100% (25/25)100% (6/6)
prune (PrunableStep): void 100% (1/1)100% (15/15)100% (4/4)
remove (): void 100% (1/1)100% (4/4)100% (1/1)
     
class Traversers$DepthFirstIterable100% (1/1)100% (3/3)100% (52/52)100% (8/8)
Traversers$DepthFirstIterable (Object, Function, Function): void 100% (1/1)100% (10/10)100% (4/4)
stepIterator (Object): Iterator 100% (1/1)100% (20/20)100% (3/3)
toString (): String 100% (1/1)100% (22/22)100% (1/1)
     
class Traversers$DepthFirstTraverser100% (1/1)100% (5/5)100% (105/105)100% (25/25)
Traversers$DepthFirstTraverser (Object, Function): void 100% (1/1)100% (23/23)100% (6/6)
hasNext (): boolean 100% (1/1)100% (8/8)100% (1/1)
next (): DepthFirstStep 100% (1/1)100% (55/55)100% (13/13)
prune (PrunableStep): void 100% (1/1)100% (15/15)100% (4/4)
remove (): void 100% (1/1)100% (4/4)100% (1/1)
     
class Traversers$DfsStep100% (1/1)100% (8/8)100% (59/59)100% (12/12)
Traversers$DfsStep (Traversers$Traverser, Traversers$DfsStep, Object): void 100% (1/1)100% (9/9)100% (3/3)
access$000 (Traversers$DfsStep): Iterator 100% (1/1)100% (3/3)100% (1/1)
descending (): int 100% (1/1)100% (3/3)100% (1/1)
isDescending (): boolean 100% (1/1)100% (7/7)100% (1/1)
iterator (): Iterator 100% (1/1)100% (3/3)100% (1/1)
setDescending (int): void 100% (1/1)100% (4/4)100% (2/2)
setIterator (Iterator): void 100% (1/1)100% (4/4)100% (2/2)
toString (): String 100% (1/1)100% (26/26)100% (1/1)
     
class Traversers$DistinctStepFunction100% (1/1)100% (2/2)100% (26/26)100% (6/6)
Traversers$DistinctStepFunction (Function, Function): void 100% (1/1)100% (12/12)100% (4/4)
apply (Object): Iterable 100% (1/1)100% (14/14)100% (2/2)
     
class Traversers$IsNewObject100% (1/1)100% (2/2)100% (21/21)100% (6/6)
Traversers$IsNewObject (Function): void 100% (1/1)100% (11/11)100% (4/4)
apply (Object): boolean 100% (1/1)100% (10/10)100% (2/2)
     
class Traversers$PriorityTraverseIterable100% (1/1)100% (3/3)100% (64/64)100% (9/9)
Traversers$PriorityTraverseIterable (Object, Function, Comparator, Function):... 100% (1/1)100% (13/13)100% (5/5)
stepIterator (Object): Iterator 100% (1/1)100% (24/24)100% (3/3)
toString (): String 100% (1/1)100% (27/27)100% (1/1)
     
class Traversers$PriorityTraverser100% (1/1)100% (6/6)100% (118/118)100% (25/25)
Traversers$PriorityTraverser (Object, Function, Comparator): void 100% (1/1)100% (32/32)100% (7/7)
addChildren (PrunableStep): void 100% (1/1)100% (26/26)100% (3/3)
hasNext (): boolean 100% (1/1)100% (8/8)100% (1/1)
next (): PrunableStep 100% (1/1)100% (20/20)100% (5/5)
prune (PrunableStep): void 100% (1/1)100% (28/28)100% (8/8)
remove (): void 100% (1/1)100% (4/4)100% (1/1)
     
class Traversers$StepComparator100% (1/1)100% (2/2)100% (14/14)100% (4/4)
Traversers$StepComparator (Comparator): void 100% (1/1)100% (6/6)100% (3/3)
compare (Step, Step): int 100% (1/1)100% (8/8)100% (1/1)
     
class Traversers$StepIterable100% (1/1)100% (3/3)100% (14/14)100% (5/5)
Traversers$StepIterable (Object): void 100% (1/1)100% (6/6)100% (3/3)
getStart (): Object 100% (1/1)100% (3/3)100% (1/1)
iterator (): Iterator 100% (1/1)100% (5/5)100% (1/1)
     
class Traversers$TraversalStep100% (1/1)100% (7/7)100% (62/62)100% (15/15)
Traversers$TraversalStep (Traversers$Traverser, Step, Object): void 100% (1/1)100% (24/24)100% (8/8)
access$100 (Traversers$TraversalStep): Object 100% (1/1)100% (3/3)100% (1/1)
getDepth (): int 100% (1/1)100% (3/3)100% (1/1)
getParent (): Step 100% (1/1)100% (3/3)100% (1/1)
getValue (): Object 100% (1/1)100% (3/3)100% (1/1)
prune (): void 100% (1/1)100% (5/5)100% (2/2)
toString (): String 100% (1/1)100% (21/21)100% (1/1)
     
class Traversers$Traverser100% (1/1)100% (1/1)100% (3/3)100% (1/1)
Traversers$Traverser (): void 100% (1/1)100% (3/3)100% (1/1)

1/*
2 * $Id: Traversers.java 594 2010-11-19 20:41:04Z PSpeed $
3 *
4 * The Filament BSD license.
5 *
6 * Copyright (c) 2009-2010, the original author or authors
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1) Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 * 2) Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3) Neither the names "Filament", "fgraph.org", "filamentgraph.org", nor the
18 *    names of its contributors may be used to endorse or promote products
19 *    derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34package org.fgraph.steps;
35 
36import java.util.*;
37 
38import com.google.common.base.Function;
39import com.google.common.base.Predicate;
40import com.google.common.collect.Iterables;
41import com.google.common.collect.Iterators;
42 
43 
44/**
45 *  Factory methods for creating traverser Iterables.
46 *
47 *  @version   $Revision: 594 $
48 *  @author    Paul Speed
49 */
50public class Traversers
51{
52    /**
53     *  Creates an Iterable that performs a pre-order depth-first
54     *  traversal starting at a specified node and using the specified
55     *  adjacency function for traversal.
56     *
57     *  <p>If an optional visitMarker function is provided then the
58     *  traversal is acyclic based on the 'marker' returned from that
59     *  function.  For example, a Functions.identity() visit marker
60     *  will make sure a node is only visited once based on its own
61     *  .equals() implementation.  A null indicates that no cycle
62     *  detection should be performed.</p>
63     */
64    public static <T> Iterable<T> preOrder( T start, Function<T,? extends Iterable<T>> fstep,
65                                            Function<? super T,? extends Object> visitMarker )
66    {
67        Iterable<DepthFirstStep<T>> pre = preOrderSteps( start, fstep, visitMarker );
68        return Iterables.transform( pre, StepFunctions.<T>unwrapStep() );
69    }
70 
71    /**
72     *  Creates a function that performs a pre-order depth-first
73     *  traversal starting at a specified node and using the specified
74     *  adjacency function for traversal, also providing additional
75     *  control over and information about the ongoing traversal.
76     *
77     *  <p>This is similar to the non-step based version except that
78     *  the traversed values are returned wrapped in DepthFirstStep
79     *  objects that provide additional information about the state
80     *  of the traversal such as depth.  These steps also allow themselves
81     *  to be 'pruned', resulting in any potential descendants being ignored
82     *  during the subsequent traverses.</p>
83     *
84     *  <p>If an optional visitMarker function is provided then the
85     *  traversal is acyclic based on the 'marker' returned from that
86     *  function.  For example, a Functions.identity() visit marker
87     *  will make sure a node is only visited once based on its own
88     *  .equals() implementation.  A null indicates that no cycle
89     *  detection should be performed.</p>
90     */
91    public static <T> Iterable<DepthFirstStep<T>> preOrderSteps( T start,
92                                                    Function<T,? extends Iterable<T>> fstep,
93                                                    Function<? super T,? extends Object> visitMarker )
94    {
95        Iterable<DepthFirstStep<T>> depth = depthFirstSteps(start, fstep, visitMarker);
96        return Iterables.filter( depth, StepPredicates.<T>descending() );
97    }
98 
99    /**
100     *  Creates a function that performs a post-order depth-first
101     *  traversal starting at a specified node and using the specified
102     *  adjacency function for traversal.
103     *
104     *  <p>If an optional visitMarker function is provided then the
105     *  traversal is acyclic based on the 'marker' returned from that
106     *  function.  For example, a Functions.identity() visit marker
107     *  will make sure a node is only visited once based on its own
108     *  .equals() implementation.  A null indicates that no cycle
109     *  detection should be performed.</p>
110     */
111    public static <T> Iterable<T> postOrder( T start, Function<T,? extends Iterable<T>> fstep,
112                                             Function<? super T,? extends Object> visitMarker )
113    {
114        Iterable<DepthFirstStep<T>> post = postOrderSteps( start, fstep, visitMarker );
115        return Iterables.transform( post, StepFunctions.<T>unwrapStep() );
116    }
117 
118    /**
119     *  Creates a function that performs a post-order depth-first
120     *  traversal starting at a specified node and using the specified
121     *  adjacency function for traversal, also providing additional
122     *  control over and information about the ongoing traversal.
123     *
124     *  <p>This is similar to the non-step based version except that
125     *  the traversed values are returned wrapped in DepthFirstStep
126     *  objects that provide additional information about the state
127     *  of the traversal such as depth.  These steps also allow themselves
128     *  to be 'pruned', resulting in any potential descendants being ignored
129     *  during the subsequent traverses.</p>
130     *
131     *  <p>If an optional visitMarker function is provided then the
132     *  traversal is acyclic based on the 'marker' returned from that
133     *  function.  For example, a Functions.identity() visit marker
134     *  will make sure a node is only visited once based on its own
135     *  .equals() implementation.  A null indicates that no cycle
136     *  detection should be performed.</p>
137     */
138    public static <T> Iterable<DepthFirstStep<T>> postOrderSteps( T start,
139                                                    Function<T,? extends Iterable<T>> fstep,
140                                                    Function<? super T,? extends Object> visitMarker )
141    {
142        Iterable<DepthFirstStep<T>> depth = depthFirstSteps( start, fstep, visitMarker );
143        return Iterables.filter( depth, StepPredicates.<T>ascending() );
144    }
145 
146    /**
147     *  Creates a function that performs a full depth-first
148     *  traversal (both pre- and post-) starting at a specified node
149     *  and using the specified adjacency function for traversal.
150     *  Every 'node' will therefore be visited twice, once descending
151     *  and once ascending.  Use the step-based depthFirstSteps()
152     *  method to distinguish descending from ascending.
153     *
154     *  <p>If an optional visitMarker function is provided then the
155     *  traversal is acyclic based on the 'marker' returned from that
156     *  function.  For example, a Functions.identity() visit marker
157     *  will make sure a node is only visited once based on its own
158     *  .equals() implementation.  A null indicates that no cycle
159     *  detection should be performed.</p>
160     */
161    public static <T> Iterable<T> depthFirst( T start, Function<T,? extends Iterable<T>> fstep,
162                                              Function<? super T,? extends Object> visitMarker )
163    {
164        Iterable<DepthFirstStep<T>> depth = depthFirstSteps( start, fstep, visitMarker );
165        return Iterables.transform( depth, StepFunctions.<T>unwrapStep() );
166    }
167 
168    /**
169     *  Creates a function that performs a full depth-first
170     *  traversal (both pre- and post-) starting at a specified node
171     *  and using the specified adjacency function for traversal,
172     *  also providing additional control over and information about
173     *  the ongoing traversal.
174     *
175     *  <p>This is similar to the non-step based version except that
176     *  the traversed values are returned wrapped in DepthFirstStep
177     *  objects that provide additional information about the state
178     *  of the traversal such as depth, descending/ascending, etc.
179     *  These steps also allow themselves to be 'pruned', resulting
180     *  in any potential descendants being ignored during the subsequent
181     *  traverses.</p>
182     *
183     *  <p>If an optional visitMarker function is provided then the
184     *  traversal is acyclic based on the 'marker' returned from that
185     *  function.  For example, a Functions.identity() visit marker
186     *  will make sure a node is only visited once based on its own
187     *  .equals() implementation.  A null indicates that no cycle
188     *  detection should be performed.</p>
189     */
190    public static <T> Iterable<DepthFirstStep<T>> depthFirstSteps( T start,
191                                                    Function<T,? extends Iterable<T>> fstep,
192                                                    Function<? super T,? extends Object> visitMarker )
193    {
194        return new DepthFirstIterable<T>( start, fstep, visitMarker );
195    }
196 
197    /**
198     *  Creates a function that performs a breadth-first
199     *  traversal starting at a specified node and using the specified
200     *  adjacency function for traversal.
201     *
202     *  <p>If an optional visitMarker function is provided then the
203     *  traversal is acyclic based on the 'marker' returned from that
204     *  function.  For example, a Functions.identity() visit marker
205     *  will make sure a node is only visited once based on its own
206     *  .equals() implementation.  A null indicates that no cycle
207     *  detection should be performed.</p>
208     */
209    public static <T> Iterable<T> breadthFirst( T start, Function<T,? extends Iterable<T>> fstep,
210                                                Function<? super T,? extends Object> visitMarker )
211    {
212        Iterable<PrunableStep<T>> breadth = breadthFirstSteps(start, fstep, visitMarker);
213        return Iterables.transform( breadth, StepFunctions.<T>unwrapStep() );
214    }
215 
216    /**
217     *  Creates a function that performs a breadth-first
218     *  traversal starting at a specified node and using the specified
219     *  adjacency function for traversal, also providing additional
220     *  control over and information about the ongoing traversal.
221     *
222     *  <p>This is similar to the non-step based version except that
223     *  the traversed values are returned wrapped in PrunableStep
224     *  objects that provide additional information about the state
225     *  of the traversal such as depth.  These steps also allow themselves
226     *  to be 'pruned', resulting in any potential descendants being ignored
227     *  during the subsequent traverses.</p>
228     *
229     *  <p>If an optional visitMarker function is provided then the
230     *  traversal is acyclic based on the 'marker' returned from that
231     *  function.  For example, a Functions.identity() visit marker
232     *  will make sure a node is only visited once based on its own
233     *  .equals() implementation.  A null indicates that no cycle
234     *  detection should be performed.</p>
235     */
236    public static <T> Iterable<PrunableStep<T>> breadthFirstSteps( T start,
237                                                    Function<T,? extends Iterable<T>> fstep,
238                                                    Function<? super T,? extends Object> visitMarker )
239    {
240        return new BreadthFirstIterable<T>( start, fstep, visitMarker );
241    }
242 
243    /**
244     *  Creates a function that performs a priority-ordered
245     *  traversal starting at a specified node and using the specified
246     *  adjacency function for traversal.
247     *
248     *  <p>The priority comparator is used to select the next step/path
249     *  from the current pending set of descendants.  For example, a
250     *  comparator could be based to select the smallest/shortest route
251     *  based on the sum of the accumulated weights/distances up to that step.</p>
252     *
253     *  <p>If an optional visitMarker function is provided then the
254     *  traversal is acyclic based on the 'marker' returned from that
255     *  function.  For example, a Functions.identity() visit marker
256     *  will make sure a node is only visited once based on its own
257     *  .equals() implementation.  A null indicates that no cycle
258     *  detection should be performed.</p>
259     */
260    public static <T> Iterable<T> priority( T start, Function<T,? extends Iterable<T>> fstep,
261                                            Comparator<? super T> priority,
262                                            Function<? super T,? extends Object> visitMarker )
263    {
264        Iterable<PrunableStep<T>> pri = prioritySteps( start, fstep, priority, visitMarker );
265        return Iterables.transform( pri, StepFunctions.<T>unwrapStep() );
266    }
267 
268    /**
269     *  Creates a function that performs a priority-ordered
270     *  traversal starting at a specified node and using the specified
271     *  adjacency function for traversal, also providing additional
272     *  control over and information about the ongoing traversal.
273     *
274     *  <p>The priority comparator is used to select the next step/path
275     *  from the current pending set of descendants.  For example, a
276     *  comparator could be based to select the smallest/shortest route
277     *  based on the sum of the accumulated weights/distances up to that step.</p>
278     *
279     *  <p>This is similar to the non-step based version except that
280     *  the traversed values are returned wrapped in PrunableStep
281     *  objects that provide additional information about the state
282     *  of the traversal such as depth.  These steps also allow themselves
283     *  to be 'pruned', resulting in any potential descendants being ignored
284     *  during the subsequent traverses.  Note: for traversals that branch
285     *  quickly, pruning a step may be a non-trivial amount of work since
286     *  it must exhaustively search the current sorted pending steps to
287     *  remove any queued descendants.</p>
288     *
289     *  <p>If an optional visitMarker function is provided then the
290     *  traversal is acyclic based on the 'marker' returned from that
291     *  function.  For example, a Functions.identity() visit marker
292     *  will make sure a node is only visited once based on its own
293     *  .equals() implementation.  A null indicates that no cycle
294     *  detection should be performed.</p>
295     */
296    public static <T> Iterable<PrunableStep<T>> prioritySteps( T start,
297                                                    Function<T,? extends Iterable<T>> fstep,
298                                                    Comparator<? super T> priority,
299                                                    Function<? super T,? extends Object> visitMarker )
300    {
301        return new PriorityTraverseIterable<T>( start, fstep, priority, visitMarker );
302    }
303 
304    /**
305     *  Method used internally to wrap an adjacency function in a
306     *  stateful function that tracks visits using the specified
307     *  visit marker function.
308     */
309    protected static <T> StepFunction<T,T> distinct( Function<T,? extends Iterable<T>> fstep,
310                                                     Function<? super T,? extends Object> visitMarker )
311    {
312        return new DistinctStepFunction<T>( visitMarker, fstep );
313    }
314 
315    /**
316     *  Internal implementation of Iterable that delegates
317     *  to the abstract stepIterator() method.
318     */
319    protected static abstract class StepIterable<S,T> implements Iterable<T>
320    {
321        private S start;
322 
323        /**
324         *  Constructs an iterable that simply delegates
325         *  to the stepIterator() method.
326         */
327        public StepIterable( S start )
328        {
329            this.start = start;
330        }
331 
332        protected S getStart()
333        {
334            return start;
335        }
336 
337        protected abstract Iterator<T> stepIterator( S start );
338 
339        /**
340         * {@inheritDoc}
341         */
342        public Iterator<T> iterator()
343        {
344            return stepIterator(start);
345        }
346    }
347 
348    private static class DepthFirstIterable<T> extends StepIterable<T,DepthFirstStep<T>>
349    {
350        private Function<T,? extends Iterable<T>> fstep;
351        private Function<? super T,? extends Object> visitMarker;
352 
353        public DepthFirstIterable( T start, Function<T,? extends Iterable<T>> fstep,
354                                   Function<? super T,? extends Object> visitMarker )
355        {
356            super( start );
357            this.fstep = fstep;
358            this.visitMarker = visitMarker;
359        }
360 
361        protected Iterator<DepthFirstStep<T>> stepIterator( T start )
362        {
363            if( visitMarker != null )
364                return new DepthFirstTraverser<T>( start, distinct( fstep, visitMarker ) );
365            return new DepthFirstTraverser<T>( start, fstep );
366        }
367 
368        public String toString()
369        {
370            return "DepthFirstIterable[start=" + getStart()
371                                    + ", delegate=" + fstep
372                                    + ", visitMarker=" + visitMarker + "]";
373        }
374    }
375 
376    /**
377     *  Function implementation that creates breadth first iterators on demand.
378     */
379    private static class BreadthFirstIterable<T> extends StepIterable<T,PrunableStep<T>>
380    {
381        private Function<T,? extends Iterable<T>> fstep;
382        private Function<? super T,? extends Object> visitMarker;
383 
384        public BreadthFirstIterable( T start, Function<T,? extends Iterable<T>> fstep,
385                                     Function<? super T,? extends Object> visitMarker )
386        {
387            super( start );
388            this.fstep = fstep;
389            this.visitMarker = visitMarker;
390        }
391 
392        protected Iterator<PrunableStep<T>> stepIterator( T start )
393        {
394            if( visitMarker != null )
395                return new BreadthFirstTraverser<T>( start, distinct( fstep, visitMarker ) );
396            return new BreadthFirstTraverser<T>( start, fstep );
397        }
398 
399        public String toString()
400        {
401            return "BreadthFirstIterable[start=" + getStart()
402                                + ", delegate=" + fstep
403                                + ", visitMarker=" + visitMarker + "]";
404        }
405    }
406 
407    /**
408     *  Function implementation that creates priority first iterators on demand.
409     */
410    private static class PriorityTraverseIterable<T> extends StepIterable<T,PrunableStep<T>>
411    {
412        private Function<T,? extends Iterable<T>> fstep;
413        private Comparator<? super T> priority;
414        private Function<? super T,? extends Object> visitMarker;
415 
416        public PriorityTraverseIterable( T start, Function<T,? extends Iterable<T>> fstep,
417                                         Comparator<? super T> priority,
418                                         Function<? super T,? extends Object> visitMarker )
419        {
420            super( start );
421            this.fstep = fstep;
422            this.priority = priority;
423            this.visitMarker = visitMarker;
424        }
425 
426        protected Iterator<PrunableStep<T>> stepIterator( T start )
427        {
428            if( visitMarker != null )
429                return new PriorityTraverser<T>( start, distinct( fstep, visitMarker ), priority );
430            return new PriorityTraverser<T>( start, fstep, priority );
431        }
432 
433        public String toString()
434        {
435            return "PriorityTraverseIterable[start=" + getStart()
436                                        + ", delegate=" + fstep
437                                        + ", priority=" + priority
438                                        + ", visitMarker=" + visitMarker + "]";
439        }
440    }
441 
442    /**
443     *  Stateful predicate returns true for newly encountered
444     *  items and adds them to an internal set.  A marker function
445     *  is used to translate raw values into visit-tracking
446     *  markers.
447     */
448    private static class IsNewObject<T> implements Predicate<T>
449    {
450        private Set<Object> visited = new HashSet<Object>();
451        private Function<? super T,? extends Object> visitMarker;
452 
453        public IsNewObject( Function<? super T,? extends Object> visitMarker )
454        {
455            this.visitMarker = visitMarker;
456        }
457 
458        public boolean apply( T value )
459        {
460            Object marker = visitMarker.apply(value);
461            return visited.add(marker);
462        }
463    }
464 
465    /**
466     *  Stateful function for returning only distinct
467     *  values.
468     */
469    private static class DistinctStepFunction<T> implements StepFunction<T,T>
470    {
471        private IsNewObject<T> newObject;
472        private Function<T, ? extends Iterable<T>> delegate;
473 
474        public DistinctStepFunction( Function<? super T,? extends Object> visitMarker,
475                                     Function<T, ? extends Iterable<T>> delegate )
476        {
477            this.newObject = new IsNewObject<T>(visitMarker);
478            this.delegate = delegate;
479        }
480 
481        public Iterable<T> apply( T value )
482        {
483            newObject.apply( value );
484            return Iterables.filter( delegate.apply( value ), newObject );
485        }
486    }
487 
488    /**
489     *  PrunableStep implementation that has reference back to its creating
490     *  Traverser for pruning.  Internally this keeps track of some data
491     *  structures useful to the traverser implementations.
492     */
493    private static class TraversalStep<T> implements PrunableStep<T>
494    {
495        private Traverser traverser;
496        private Step parent;
497        private int depth;
498        private T node;
499 
500        public TraversalStep( Traverser traverser, Step parent, T node )
501        {
502            this.traverser = traverser;
503            this.parent = parent;
504            this.node = node;
505            if( parent == null )
506                depth = 0;
507            else
508                depth = parent.getDepth() + 1;
509        }
510 
511        public T getValue()
512        {
513            return node;
514        }
515 
516        public int getDepth()
517        {
518            return depth;
519        }
520 
521        public Step getParent()
522        {
523            return parent;
524        }
525 
526        public void prune()
527        {
528            traverser.prune(this);
529        }
530 
531        public String toString()
532        {
533            return getClass().getSimpleName() + "[" + node + ", " + depth + "]";
534        }
535    }
536 
537    /**
538     *  Depth first specific step implementation.
539     */
540    private static class DfsStep<T> extends TraversalStep<T>
541                                    implements DepthFirstStep<T>
542    {
543        private Iterator<T> it;
544        private int descending = -1;
545 
546        public DfsStep( Traverser traverser, DfsStep<T> parent, T node )
547        {
548            super( traverser, parent, node );
549        }
550 
551        protected Iterator<T> iterator()
552        {
553            return it;
554        }
555 
556        protected void setIterator( Iterator<T> it )
557        {
558            this.it = it;
559        }
560 
561        protected int descending()
562        {
563            return descending;
564        }
565 
566        protected void setDescending( int descending )
567        {
568            this.descending = descending;
569        }
570 
571        public boolean isDescending()
572        {
573            return descending <= 0;
574        }
575 
576        public String toString()
577        {
578            return getClass().getSimpleName() + "[" + getValue() + ", " + getDepth()
579                                              + ", " + isDescending() + "]";
580        }
581    }
582 
583    /**
584     *  Base class for the various traverser iterator implementations.
585     *  Exposes an abstract prune() that the specific implementations
586     *  must implement.
587     */
588    protected abstract static class Traverser<T> implements Iterator<T>
589    {
590        /**
591         *  Implemented by the specific traversers to provide
592         *  implementation specific pruning.
593         */
594        protected abstract void prune( PrunableStep step );
595    }
596 
597    /**
598     *  The depth-first stateful traversal implementation.
599     */
600    private static class DepthFirstTraverser<T> extends Traverser<DepthFirstStep<T>>
601    {
602        private T start;
603        private Function<T,? extends Iterable<T>> fstep;
604        private LinkedList<DfsStep<T>> stack = new LinkedList<DfsStep<T>>();
605 
606        public DepthFirstTraverser( T start, Function<T,? extends Iterable<T>> fstep )
607        {
608            this.start = start;
609            this.fstep = fstep;
610            stack.addFirst( new DfsStep<T>(this, null, start) );
611        }
612 
613        protected void prune( PrunableStep step )
614        {
615            // For now, we'll only support pruning the current level...
616            // though there's not a strong reason not to support multi-level
617            // pruning it just seems a little dangerous.
618            if( stack.getFirst() != step )
619                throw new IllegalStateException( "Pruned step is not current." );
620 
621            // Otherwise, just remove it
622            stack.removeFirst();
623        }
624 
625        public boolean hasNext()
626        {
627            // Since we remove the last item when we're done
628            // then this is enough of a check... since
629            // even an item with no children is returned on
630            // exit (and then removed).
631            return !stack.isEmpty();
632        }
633 
634        public DepthFirstStep<T> next()
635        {
636            while( true )
637                {
638                // See what the state of the top item is
639                DfsStep<T> top = stack.getFirst();
640 
641                if( top.iterator() == null && top.descending() < 0 )
642                    {
643                    // Mark it as leveling off and we'll create
644                    // the iterator the next time through
645                    top.setDescending(0);
646                    return top; // descending
647                    }
648                else if( top.iterator() == null )
649                    {
650                    top.setIterator( fstep.apply( top.getValue() ).iterator() );
651                    }
652 
653                if( !top.it.hasNext() )
654                    {
655                    // Then we're done with this level
656                    stack.removeFirst();
657                    top.setDescending(1);
658                    return top; // ascending
659                    }
660 
661                // Otherwise, just return the next element in
662                // the steps iterator
663                T result = top.iterator().next();
664                stack.addFirst( new DfsStep<T>(this, top, result) );
665                }
666        }
667 
668        public void remove()
669        {
670            throw new UnsupportedOperationException();
671        }
672    }
673 
674    /**
675     *  The breadth-first stateful traversal implementation.
676     */
677    private static class BreadthFirstTraverser<T> extends Traverser<PrunableStep<T>>
678    {
679        private T start;
680        private Function<T,? extends Iterable<T>> fstep;
681        private LinkedList<TraversalStep<T>> queue = new LinkedList<TraversalStep<T>>();
682        private TraversalStep<T> parent;
683        private Iterator<T> current;
684 
685        public BreadthFirstTraverser( T start, Function<T,? extends Iterable<T>> fstep )
686        {
687            this.start = start;
688            this.fstep = fstep;
689            parent = null;
690            current = Iterators.singletonIterator(start);
691        }
692 
693        protected void prune( PrunableStep step )
694        {
695            // In this implementation of breadth-first traveral,
696            // when the current value has been returned, the
697            // step is added to the end of the queue and it's
698            // from there that we should remove it.
699            if( queue.getLast() != step )
700                throw new IllegalStateException( "Pruned step is not current." );
701            queue.removeLast();
702        }
703 
704        public boolean hasNext()
705        {
706            if( current.hasNext() )
707                return true;
708 
709            while( !queue.isEmpty() )
710                {
711                parent = queue.removeFirst();
712                current = fstep.apply( parent.node ).iterator();
713                if( current.hasNext() )
714                    return true;
715                }
716 
717            return false;
718        }
719 
720        public PrunableStep<T> next()
721        {
722            if( !hasNext() )
723                throw new NoSuchElementException();
724 
725            // At this point we are guaranteed to have a current
726            // iterator with stuff still in it.
727            T next = current.next();
728            TraversalStep<T> result = new TraversalStep<T>(this, parent, next);
729            queue.addLast( result );
730 
731            return result;
732        }
733 
734        public void remove()
735        {
736            throw new UnsupportedOperationException();
737        }
738    }
739 
740    /**
741     *  Comparator that can unwrap steps for comparison by a delegate
742     *  comparator.  This is used by the PriorityTraverser to priority
743     *  sort the pending steps.
744     */
745    private static class StepComparator<T> implements Comparator<Step<T>>
746    {
747        private Comparator<? super T> delegate;
748 
749        public StepComparator( Comparator<? super T> delegate )
750        {
751            this.delegate = delegate;
752        }
753 
754        public int compare( Step<T> s1, Step<T> s2 )
755        {
756            return delegate.compare( s1.getValue(), s2.getValue() );
757        }
758    }
759 
760    /**
761     *  The priority-ordered stateful traversal implementation.
762     */
763    private static class PriorityTraverser<T> extends Traverser<PrunableStep<T>>
764    {
765        private static final int INITIAL_CAPACITY = 11; // the same as PriorityQueue's default
766 
767        private T start;
768        private Function<T,? extends Iterable<T>> fstep;
769        private Comparator<? super T> priority;
770 
771        private PriorityQueue<PrunableStep<T>> pending;
772        private PrunableStep<T> last;
773 
774        public PriorityTraverser( T start, Function<T,? extends Iterable<T>> fstep,
775                                  Comparator<? super T> priority )
776        {
777            this.start = start;
778            this.fstep = fstep;
779            this.priority = priority;
780 
781            this.pending = new PriorityQueue<PrunableStep<T>>( INITIAL_CAPACITY,
782                                                               new StepComparator<T>(priority) );
783            pending.add( new TraversalStep<T>( this, null, start ) );
784        }
785 
786        protected void addChildren( PrunableStep<T> parent )
787        {
788            for( T child : fstep.apply( parent.getValue() ) )
789                {
790                pending.add( new TraversalStep<T>( this, parent, child ) );
791                }
792        }
793 
794        protected void prune( PrunableStep step )
795        {
796            // If the step isn't the last one returned then
797            // we don't allow it.  In this case, it really is
798            // tricky to implement that.
799            if( step != last )
800                throw new IllegalStateException( "Pruned step is not current." );
801 
802            // Remove any steps that have the specified step
803            // as parent.  There is no cheap way to do this
804            for( Iterator<PrunableStep<T>> i = pending.iterator(); i.hasNext(); )
805                {
806                PrunableStep s = i.next();
807                if( s.getParent() == step )
808                    i.remove();
809                }
810        }
811 
812        public boolean hasNext()
813        {
814            return !pending.isEmpty();
815        }
816 
817        public PrunableStep<T> next()
818        {
819            if( !hasNext() )
820                throw new NoSuchElementException();
821 
822            // Grab the top of the queue
823            last = pending.remove();
824 
825            // Fetch any next level steps before returning
826            addChildren( last );
827 
828            return last;
829        }
830 
831        public void remove()
832        {
833            throw new UnsupportedOperationException();
834        }
835    }
836}
837 

[all classes][org.fgraph.steps]
EMMA 2.0.5312 (C) Vladimir Roubtsov