001: /*
002: * Copyright (c) 2000 by Matt Welsh and The Regents of the University of
003: * California. All rights reserved.
004: *
005: * Permission to use, copy, modify, and distribute this software and its
006: * documentation for any purpose, without fee, and without written agreement is
007: * hereby granted, provided that the above copyright notice and the following
008: * two paragraphs appear in all copies of this software.
009: *
010: * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
011: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
012: * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
013: * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
014: *
015: * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
016: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
017: * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
018: * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
019: * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
020: *
021: * Author: Matt Welsh <mdw@cs.berkeley.edu>
022: *
023: */
024:
025: package seda.sandStorm.lib.aDisk;
026:
027: import seda.sandStorm.api.*;
028: import seda.sandStorm.core.*;
029: import java.io.*;
030:
031: /**
032: * This class represents an asynchronous file I/O interface.
033: * <p>
034: * To use this class, the user creates an AFile corresponding to a given
035: * filename. AFile implements SinkIF, and as such you can enqueue
036: * I/O requests to be performed on this file; all such requests must be
037: * subclasses of AFileRequest. The <tt>read</tt>, <tt>write</tt>, and
038: * <tt>seek</tt> methods are also provided for convenience.
039: *
040: * @author Matt Welsh
041: * @see SinkIF, AFileRequest
042: */
043: public class AFile extends SimpleSink {
044:
045: private String fname;
046: private AFileImpl impl;
047: private SinkIF compQ;
048:
049: /**
050: * Open the file with the given pathname.
051: *
052: * @param name A system-dependent filename.
053: * @param compQ The default completion queue on which read and write
054: * completion events will be posted. A completion queue can
055: * be specified for each individual request by setting the 'compQ'
056: * field in the associated AFileRequest.
057: * @param create If true, creates the file if it does not exist.
058: * @param create If true, opens the file in read-only mode.
059: *
060: * @exception FileNotFoundException If the file does not exist and
061: * 'create' is false.
062: */
063: public AFile(String name, SinkIF compQ, boolean create,
064: boolean readOnly) throws IOException {
065: AFileMgr.initialize();
066: this .compQ = compQ;
067: this .fname = name;
068:
069: switch (AFileMgr.getImpl()) {
070: case AFileMgr.THREADPOOL_IMPL:
071: impl = new AFileTPImpl(this , name, compQ, create, readOnly,
072: (AFileTPTM) AFileMgr.getTM());
073: break;
074: default:
075: throw new LinkageError(
076: "Error: AFileMgr has bad value for IMPL_TO_USE; this is a bug - please contact <mdw@cs.berkeley.edu>");
077: }
078: }
079:
080: /**
081: * Enqueues the given request (which must be an AFileRequest)
082: * to the file.
083: */
084: public synchronized void enqueue(QueueElementIF req)
085: throws SinkException {
086: impl.enqueue(req);
087: }
088:
089: /**
090: * Enqueues the given request (which must be an AFileRequest)
091: * to the file.
092: */
093: public synchronized boolean enqueue_lossy(QueueElementIF req) {
094: return impl.enqueue_lossy(req);
095: }
096:
097: /**
098: * Enqueues the given requests (which must be AFileRequests)
099: * to the file.
100: */
101: public synchronized void enqueue_many(QueueElementIF[] elements)
102: throws SinkException {
103: impl.enqueue_many(elements);
104: }
105:
106: // The following are convenience methods ---------------------------------
107:
108: /**
109: * Enqueues a write request at the current file offset.
110: */
111: public synchronized void write(BufferElement buf)
112: throws SinkException {
113: this .enqueue(new AFileWriteRequest(buf, compQ));
114: }
115:
116: /**
117: * Enqueues a write request at the given file offset. This is
118: * equivalent to a call to seek() before write().
119: */
120: public synchronized void write(BufferElement buf, int offset)
121: throws SinkException {
122: this .enqueue(new AFileSeekRequest(offset, null));
123: this .enqueue(new AFileWriteRequest(buf, compQ));
124: }
125:
126: /**
127: * Enqueues a read request at the current file offset.
128: */
129: public synchronized void read(BufferElement buf)
130: throws SinkException {
131: this .enqueue(new AFileReadRequest(buf, compQ));
132: }
133:
134: /**
135: * Enqueues a read request at the given file offset. This is equivalent
136: * to a call to seek() before read().
137: */
138: public synchronized void read(BufferElement buf, int offset)
139: throws SinkException {
140: this .enqueue(new AFileSeekRequest(offset, null));
141: this .enqueue(new AFileReadRequest(buf, compQ));
142: }
143:
144: /**
145: * Position the file to the given offset. As with read and writes,
146: * seek requests are performed asynchronously; only read and write
147: * requests enqueued after the seek operation will use the new file
148: * offset.
149: */
150: public synchronized void seek(int offset) throws SinkException {
151: this .enqueue(new AFileSeekRequest(offset, compQ));
152: }
153:
154: /**
155: * Return information on the properties of the file.
156: */
157: public AFileStat stat() {
158: return impl.stat();
159: }
160:
161: public String getFilename() {
162: return fname;
163: }
164:
165: /**
166: * Close the file after all enqueued requests have completed.
167: * Disallows any additional requests to be enqueued on this file.
168: * A SinkClosedEvent will be posted on the file's completion queue
169: * when the close is complete.
170: */
171: public synchronized void close() {
172: impl.close();
173: }
174:
175: /**
176: * Causes a SinkFlushedEvent to be posted on the file's completion queue
177: * when all pending requests have completed.
178: */
179: public synchronized void flush() {
180: impl.flush();
181: }
182:
183: /**
184: * Returns the implementation-specific object representing this AFile.
185: * Package access only.
186: */
187: AFileImpl getImpl() {
188: return impl;
189: }
190:
191: public String toString() {
192: return "AFile [fname=" + fname + "]";
193: }
194:
195: }
|