View Javadoc
1   //******************************************************************************
2   //
3   // File:    JobGenerator.java
4   // Package: edu.rit.pj.job
5   // Unit:    Class edu.rit.pj.job.JobGenerator
6   //
7   // This Java source file is copyright (C) 2010 by Alan Kaminsky. All rights
8   // reserved. For further information, contact the author, Alan Kaminsky, at
9   // ark@cs.rit.edu.
10  //
11  // This Java source file is part of the Parallel Java Library ("PJ"). PJ is free
12  // software; you can redistribute it and/or modify it under the terms of the GNU
13  // General Public License as published by the Free Software Foundation; either
14  // version 3 of the License, or (at your option) any later version.
15  //
16  // PJ is distributed in the hope that it will be useful, but WITHOUT ANY
17  // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18  // A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19  //
20  // Linking this library statically or dynamically with other modules is making a
21  // combined work based on this library. Thus, the terms and conditions of the GNU
22  // General Public License cover the whole combination.
23  //
24  // As a special exception, the copyright holders of this library give you
25  // permission to link this library with independent modules to produce an
26  // executable, regardless of the license terms of these independent modules, and
27  // to copy and distribute the resulting executable under terms of your choice,
28  // provided that you also meet, for each linked independent module, the terms
29  // and conditions of the license of that module. An independent module is a module
30  // which is not derived from or based on this library. If you modify this library,
31  // you may extend this exception to your version of the library, but you are not
32  // obligated to do so. If you do not wish to do so, delete this exception
33  // statement from your version.
34  //
35  // A copy of the GNU General Public License is provided in the file gpl.txt. You
36  // may also obtain a copy of the GNU General Public License on the World Wide
37  // Web at http://www.gnu.org/licenses/gpl.html.
38  //
39  //******************************************************************************
40  package edu.rit.pj.job;
41  
42  import java.util.HashSet;
43  import java.util.Iterator;
44  import java.util.NoSuchElementException;
45  import java.util.Set;
46  
47  /**
48   * Class JobGenerator is the abstract base class for an object that generates a
49   * group of {@linkplain Job}s.
50   * <P>
51   * Jobs are numbered from 0 to <I>N</I>&minus;1, where <I>N</I> is the number of
52   * jobs in the group. A subclass must override the <code>jobCount()</code> method to
53   * return <I>N</I>. A subclass must override the <code>createJob()</code> method to
54   * create and return the job corresponding to a given job number. The job
55   * generator need not create all the jobs in the group, and it need not create
56   * them in any particular order.
57   * <P>
58   * Class JobGenerator provides the <code>omit()</code> method to omit generating
59   * certain job numbers. This is used for checkpointing. For further information,
60   * see class {@linkplain Runner}.
61   *
62   * @author Alan Kaminsky
63   * @version 08-Oct-2010
64   */
65  public abstract class JobGenerator
66          implements Iterable<Job> {
67  
68  // Hidden data members.
69      private Set<Integer> myOmittedJobNumbers;
70  
71  // Exported constructors.
72      /**
73       * Construct a new job generator.
74       */
75      public JobGenerator() {
76          myOmittedJobNumbers = new HashSet<Integer>();
77      }
78  
79  // Exported operations.
80      /**
81       * Omit the job numbers in the given set when generating jobs. To be
82       * effective, <code>omit()</code> must be called before calling
83       * <code>iterator()</code>. A snapshot of the given set is taken; changing the
84       * set's contents thereafter will not affect the job numbers to be omitted.
85       *
86       * @param theOmittedJobNumbers Set of job numbers to be omitted.
87       * @exception NullPointerException (unchecked exception) Thrown if
88       * <code>theOmittedJobNumbers</code> is null.
89       */
90      public void omit(Set<Integer> theOmittedJobNumbers) {
91          myOmittedJobNumbers.clear();
92          myOmittedJobNumbers.addAll(theOmittedJobNumbers);
93      }
94  
95      /**
96       * Get an iterator for generating the jobs in the job group.
97       *
98       * @return Iterator.
99       */
100     public Iterator<Job> iterator() {
101         return new Iterator<Job>() {
102             private int N = jobCount();
103             private int myJobNumber = -1;
104             private boolean generated = true;
105 
106             public boolean hasNext() {
107                 advance();
108                 return myJobNumber < N;
109             }
110 
111             public Job next() {
112                 advance();
113                 if (myJobNumber >= N) {
114                     throw new NoSuchElementException();
115                 }
116                 generated = true;
117                 return createJob(myJobNumber);
118             }
119 
120             public void remove() {
121                 throw new UnsupportedOperationException();
122             }
123 
124             private void advance() {
125                 if (generated) {
126                     generated = false;
127                     do {
128                         ++myJobNumber;
129                     } while (myJobNumber < N
130                             && myOmittedJobNumbers.contains(myJobNumber));
131                 }
132             }
133         };
134     }
135 
136 // Hidden operations.
137     /**
138      * Returns the number of jobs in the job group, <I>N</I>.
139      *
140      * @return Number of jobs.
141      */
142     protected abstract int jobCount();
143 
144     /**
145      * Create the job with the given job number. This method must create and
146      * return an instance of class {@linkplain Job} whose job number is
147      * <code>theJobNumber</code>.
148      *
149      * @param theJobNumber Job number (0 .. <I>N</I>&minus;1).
150      * @return a {@link edu.rit.pj.job.Job} object.
151      */
152     protected abstract Job createJob(int theJobNumber);
153 
154 }