1 //******************************************************************************
2 //
3 // File: BackendFileWriter.java
4 // Package: edu.rit.pj.cluster
5 // Unit: Class edu.rit.pj.cluster.BackendFileWriter
6 //
7 // This Java source file is copyright (C) 2006 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.cluster;
41
42 import java.io.File;
43 import java.io.IOException;
44 import java.io.PrintStream;
45 import java.util.HashMap;
46 import java.util.Map;
47
48 import edu.rit.io.LineBufferedOutputStream;
49
50 /**
51 * Class BackendFileWriter provides an object that writes sequential files in
52 * the job backend process.
53 * <P>
54 * <I>Note:</I> Class BackendFileWriter is not multiple thread safe; it assumes
55 * it is being called by a synchronized method in the job backend.
56 *
57 * @author Alan Kaminsky
58 * @version 05-Nov-2006
59 */
60 public class BackendFileWriter {
61
62 // Exported data members.
63 /**
64 * Print stream for printing on the job frontend's standard output.
65 */
66 public final PrintStream out;
67
68 /**
69 * Print stream for printing on the job frontend's standard error.
70 */
71 public final PrintStream err;
72
73 // Hidden data members.
74 private JobFrontendRef myJobFrontend;
75 private JobBackendRef myJobBackend;
76
77 // Mapping from backend file descriptor to backend file output stream.
78 private Map<Integer, BackendFileOutputStream> myOutputStreamForBFD
79 = new HashMap<Integer, BackendFileOutputStream>();
80
81 // Mapping from frontend file descriptor to backend file output stream.
82 private Map<Integer, BackendFileOutputStream> myOutputStreamForFFD
83 = new HashMap<Integer, BackendFileOutputStream>();
84
85 // Next backend file descriptor.
86 private int myNextBFD = 1;
87
88 // Exported constructors.
89 /**
90 * Construct a new backend file writer.
91 *
92 * @param theJobFrontend Job Frontend.
93 * @param theJobBackend Job Backend.
94 */
95 public BackendFileWriter(JobFrontendRef theJobFrontend,
96 JobBackendRef theJobBackend) {
97 myJobFrontend = theJobFrontend;
98 myJobBackend = theJobBackend;
99
100 // Set up output streams for stdout and stderr.
101 BackendFileOutputStream outstream
102 = new BackendFileOutputStream(myJobFrontend, myJobBackend, 1);
103 BackendFileOutputStream errstream
104 = new BackendFileOutputStream(myJobFrontend, myJobBackend, 2);
105 myOutputStreamForFFD.put(1, outstream);
106 myOutputStreamForFFD.put(2, errstream);
107
108 // Set up print streams for stdout and stderr.
109 out
110 = new PrintStream(new LineBufferedOutputStream(outstream),
111 true);
112 err
113 = new PrintStream(new LineBufferedOutputStream(errstream),
114 true);
115 }
116
117 // Exported operations.
118 /**
119 * Open a backend file output stream on the given file.
120 *
121 * @param file File.
122 * @param append True to append, false to overwrite.
123 * @return Backend file output stream.
124 * @exception IOException Thrown if an I/O error occurred.
125 * @throws java.io.IOException if any.
126 */
127 public BackendFileOutputStream open(File file,
128 boolean append)
129 throws IOException {
130 BackendFileOutputStream stream = null;
131 int bfd = 0;
132 int ffd = 0;
133
134 synchronized (this) {
135 stream = new BackendFileOutputStream(myJobFrontend, myJobBackend);
136 bfd = myNextBFD++;
137 myOutputStreamForBFD.put(bfd, stream);
138 }
139
140 ffd = stream.open(bfd, file, append);
141
142 synchronized (this) {
143 myOutputStreamForFFD.put(ffd, stream);
144 }
145 return stream;
146 }
147
148 /**
149 * Report the result of opening the given output file.
150 *
151 * @param theJobFrontend Job Frontend that is calling this method.
152 * @param bfd Backend file descriptor.
153 * @param ffd Frontend file descriptor if success.
154 * @param exc Null if success, exception if failure.
155 */
156 public void outputFileOpenResult(JobFrontendRef theJobFrontend,
157 int bfd,
158 int ffd,
159 IOException exc) {
160 BackendFileOutputStream stream = null;
161 synchronized (this) {
162 stream = myOutputStreamForBFD.remove(bfd);
163 }
164 if (stream != null) {
165 stream.putResult(ffd, exc);
166 }
167 }
168
169 /**
170 * Report the result of writing the given output file.
171 *
172 * @param theJobFrontend Job Frontend that is calling this method.
173 * @param ffd Frontend file descriptor.
174 * @param exc Null if success, exception if failure.
175 */
176 public void outputFileWriteResult(JobFrontendRef theJobFrontend,
177 int ffd,
178 IOException exc) {
179 BackendFileOutputStream stream = null;
180 synchronized (this) {
181 stream = myOutputStreamForFFD.get(ffd);
182 }
183 if (stream != null) {
184 stream.putResult(ffd, exc);
185 }
186 }
187
188 /**
189 * Report the result of flushing the given output file.
190 *
191 * @param theJobFrontend Job Frontend that is calling this method.
192 * @param ffd Frontend file descriptor.
193 * @param exc Null if success, exception if failure.
194 */
195 public void outputFileFlushResult(JobFrontendRef theJobFrontend,
196 int ffd,
197 IOException exc) {
198 BackendFileOutputStream stream = null;
199 synchronized (this) {
200 stream = myOutputStreamForFFD.get(ffd);
201 }
202 if (stream != null) {
203 stream.putResult(ffd, exc);
204 }
205 }
206
207 /**
208 * Report the result of closing the given output file.
209 *
210 * @param theJobFrontend Job Frontend that is calling this method.
211 * @param ffd Frontend file descriptor.
212 * @param exc Null if success, exception if failure.
213 */
214 public void outputFileCloseResult(JobFrontendRef theJobFrontend,
215 int ffd,
216 IOException exc) {
217 BackendFileOutputStream stream = null;
218 synchronized (this) {
219 stream = myOutputStreamForFFD.remove(ffd);
220 }
221 if (stream != null) {
222 stream.putResult(ffd, exc);
223 }
224 }
225
226 }