View Javadoc

1   package org.lcsim.util.loop;
2   
3   import java.io.EOFException;
4   import java.io.File;
5   import java.io.FileNotFoundException;
6   import java.io.IOException;
7   import java.util.Arrays;
8   import java.util.Collections;
9   import java.util.List;
10  
11  import org.freehep.record.source.AbstractRecordSource;
12  import org.freehep.record.source.NoSuchRecordException;
13  import org.lcsim.event.EventHeader;
14  import org.lcsim.lcio.*;
15  
16  /**
17   * Convert an LCIOReader to a SequentialRecordSource
18   * @author tonyj
19   * @version $Id: LCIOEventSource.java,v 1.7 2012/07/02 21:50:17 jeremy Exp $
20   */
21  public class LCIOEventSource extends AbstractRecordSource {
22  
23    private List<File> files;
24    private boolean atEnd = false;
25    private boolean atStart = true;
26    private LCIOReader reader;
27    private EventHeader currentEvent;
28    private int currentFile = 0;
29    
30    private long _index = -1L;
31    private long[] _size;
32  
33    /**
34     * Create an LCIO event source for reading a single LCIO file
35     *
36     * @param file The file to read
37     */
38    public LCIOEventSource(File file) throws IOException {
39      super(file.getName());
40      this.reader = new LCIOReader(file);
41      this.files = Collections.singletonList(file);
42      _size = new long[1]; _size[0] = -1L;
43    }
44  
45    /**
46     * Create an LCIO event source for reading a set of LCIO files.
47     *
48     * @param name The name of the collection of event files
49     * @param files The list of files to read.
50     */
51    public LCIOEventSource(String name, List<File> files) throws IOException {
52      super(name);
53      if (files.isEmpty()) throw new IOException("File list is empty");
54      this.reader = new LCIOReader(files.get(0));
55      this.files = files;
56      _size = new long[files.size()]; Arrays.fill(_size, -1L);
57    }
58  
59    /**
60     * Create an LCIO event source that will read a set of LCIO files
61     *
62     * @param list The list of files to open
63     */
64    public LCIOEventSource(FileList list) throws FileNotFoundException, IOException {
65      super(list.getTitle());
66      this.files = list.getFileList();
67      if (files.isEmpty()) throw new IOException("File list is empty");
68      this.reader = new LCIOReader(files.get(0));
69      _size = new long[files.size()]; Arrays.fill(_size, -1L);
70    }
71  
72    
73    public Object getCurrentRecord() throws IOException {
74      if (_index == -1L) throw new IllegalStateException();
75      if (currentEvent == null) throw new IOException();
76      return currentEvent;
77    }
78    
79    public long getCurrentIndex() {
80      return _index;
81    }
82  
83    public Class<?> getRecordClass() {
84      return EventHeader.class;
85    }
86    
87    public boolean supportsCurrent() {return true;}
88  
89    public boolean supportsNext() {return true;}
90    
91    public boolean supportsPrevious() {return true;}
92    
93    public boolean supportsIndex() {return true;}
94    
95    public boolean supportsShift() {return true;}
96    
97    public boolean supportsRewind() {return true;}
98  
99    public boolean hasCurrent() {
100     return _index != -1L;
101   }
102 
103   public boolean hasNext() {
104     return !atEnd;
105   }
106   public boolean hasPrevious() {
107     return _index > 0L;
108   }
109 
110   public boolean hasIndex(long index) {
111     return index >= 0L;
112   }
113 
114   public boolean hasShift(long numberOfRecords) {
115     return hasIndex(_index + numberOfRecords);
116   }
117   
118   public boolean hasRewind() {
119     return _index != -1L;
120   }
121   
122   public void current() throws IOException, NoSuchRecordException {
123     jump(_index);
124   }
125 
126   public void next() throws IOException, NoSuchRecordException {
127     for (;;) {
128       try {
129         currentEvent = reader.read();
130         //currentEvent.put("INPUT_FILE", files.get(currentFile));
131         _index++;
132       } catch (EOFException x) {
133         _size[currentFile] = _index;
134         if (currentFile + 1 >= files.size()) {
135           atEnd = true;
136           throw new NoSuchRecordException();
137         } else {
138           currentFile++;
139           reader.close();
140           reader = new LCIOReader(files.get(currentFile));
141           continue;
142         }
143       }
144       return;
145     }
146   }
147   
148   public void previous() throws IOException, NoSuchRecordException {
149     jump(_index-1);
150   }
151   
152   public void jump(long index) throws IOException, NoSuchRecordException {
153     if (index < 0L) throw new NoSuchRecordException();
154     long i = _index;
155     int f = -1;
156     while (++f < files.size() && _size[f] != -1L && _size[f] < index);
157     if (f >= files.size()) throw new NoSuchRecordException();
158     atEnd = false;
159     long recoveryTarget = _index;
160     if (f != currentFile || index <= _index) {
161       reader.close();
162       reader = new LCIOReader(files.get(f));
163       i = (f == 0) ? -1L : _size[f-1];
164     }
165     int skipMax = Integer.MAX_VALUE - 10;
166     for (long skip = index - i - 1L; skip > 0L; ) {
167       int skipNow = skip > skipMax ? skipMax : (int)skip ;
168       skip -= skipNow;
169       while (true) {
170         int skipped = reader.skipEventsChecked(skipNow);
171         i += skipped;
172         if (skipped == skipNow) {
173           break;
174         } else {
175           skipNow -= skipped;
176           reader.close();
177           _size[f++] = i;
178           if (f < files.size()) {
179             reader = new LCIOReader(files.get(f));
180           } else {
181             reader = new LCIOReader(files.get(0));
182             if (_index != -1L) {
183               currentFile = 0;
184               atEnd = false;
185               _index = -1L;
186               try {
187                 jump(recoveryTarget);
188               } catch (NoSuchRecordException x) {
189                 throw new IOException(x);
190               }
191             }
192             throw new NoSuchRecordException();
193           }
194         }
195       }
196     }
197     _index = i;
198     currentFile = f;
199     try {
200       next();
201     } catch (NoSuchRecordException x) {
202       try {
203         jump(recoveryTarget);
204       } catch (NoSuchRecordException xx) {
205         throw new IOException(x);
206       }
207     }
208   }
209   
210   public void shift(long numberOfRecords) throws IOException, NoSuchRecordException {
211     jump(_index + numberOfRecords);
212   }
213 
214   public void rewind() throws IOException {
215     currentFile = 0;
216     reader.close();
217     reader = new LCIOReader(files.get(currentFile));
218     atEnd = false;
219     _index = -1L;
220     currentEvent = null;
221   }
222 
223   public void close() throws IOException {
224     if (reader != null) {
225       reader.close();
226       reader = null;
227     }
228     currentEvent = null;
229   }
230 
231   public void releaseRecord(Object obj) {
232     currentEvent = null;
233   }
234 
235   public void finalize() {
236     try {
237       close();
238     } catch (IOException x) {
239     }
240   }
241 }