1 package org.apache.lucene.index; 2 3 18 19 import org.apache.lucene.store.Directory; 20 import org.apache.lucene.store.IndexInput; 21 import org.apache.lucene.store.BufferedIndexInput; 22 import org.apache.lucene.store.IndexOutput; 23 import org.apache.lucene.store.Lock; 24 25 import java.util.HashMap ; 26 import java.io.IOException ; 27 28 29 37 class CompoundFileReader extends Directory { 38 39 private static final class FileEntry { 40 long offset; 41 long length; 42 } 43 44 45 private Directory directory; 47 private String fileName; 48 49 private IndexInput stream; 50 private HashMap entries = new HashMap (); 51 52 53 public CompoundFileReader(Directory dir, String name) 54 throws IOException 55 { 56 directory = dir; 57 fileName = name; 58 59 boolean success = false; 60 61 try { 62 stream = dir.openInput(name); 63 64 int count = stream.readVInt(); 66 FileEntry entry = null; 67 for (int i=0; i<count; i++) { 68 long offset = stream.readLong(); 69 String id = stream.readString(); 70 71 if (entry != null) { 72 entry.length = offset - entry.offset; 74 } 75 76 entry = new FileEntry(); 77 entry.offset = offset; 78 entries.put(id, entry); 79 } 80 81 if (entry != null) { 83 entry.length = stream.length() - entry.offset; 84 } 85 86 success = true; 87 88 } finally { 89 if (! success && (stream != null)) { 90 try { 91 stream.close(); 92 } catch (IOException e) { } 93 } 94 } 95 } 96 97 public Directory getDirectory() { 98 return directory; 99 } 100 101 public String getName() { 102 return fileName; 103 } 104 105 public synchronized void close() throws IOException { 106 if (stream == null) 107 throw new IOException ("Already closed"); 108 109 entries.clear(); 110 stream.close(); 111 stream = null; 112 } 113 114 public synchronized IndexInput openInput(String id) 115 throws IOException 116 { 117 if (stream == null) 118 throw new IOException ("Stream closed"); 119 120 FileEntry entry = (FileEntry) entries.get(id); 121 if (entry == null) 122 throw new IOException ("No sub-file with id " + id + " found"); 123 124 return new CSIndexInput(stream, entry.offset, entry.length); 125 } 126 127 128 public String [] list() { 129 String res[] = new String [entries.size()]; 130 return (String []) entries.keySet().toArray(res); 131 } 132 133 134 public boolean fileExists(String name) { 135 return entries.containsKey(name); 136 } 137 138 139 public long fileModified(String name) throws IOException { 140 return directory.fileModified(fileName); 141 } 142 143 144 public void touchFile(String name) throws IOException { 145 directory.touchFile(fileName); 146 } 147 148 150 public void deleteFile(String name) 151 { 152 throw new UnsupportedOperationException (); 153 } 154 155 157 public void renameFile(String from, String to) 158 { 159 throw new UnsupportedOperationException (); 160 } 161 162 164 public long fileLength(String name) 165 throws IOException 166 { 167 FileEntry e = (FileEntry) entries.get(name); 168 if (e == null) 169 throw new IOException ("File " + name + " does not exist"); 170 return e.length; 171 } 172 173 175 public IndexOutput createOutput(String name) 176 { 177 throw new UnsupportedOperationException (); 178 } 179 180 182 public Lock makeLock(String name) 183 { 184 throw new UnsupportedOperationException (); 185 } 186 187 192 static final class CSIndexInput extends BufferedIndexInput { 193 194 IndexInput base; 195 long fileOffset; 196 long length; 197 198 CSIndexInput(final IndexInput base, final long fileOffset, final long length) 199 { 200 this.base = base; 201 this.fileOffset = fileOffset; 202 this.length = length; 203 } 204 205 211 protected void readInternal(byte[] b, int offset, int len) 212 throws IOException 213 { 214 synchronized (base) { 215 long start = getFilePointer(); 216 if(start + len > length) 217 throw new IOException ("read past EOF"); 218 base.seek(fileOffset + start); 219 base.readBytes(b, offset, len); 220 } 221 } 222 223 227 protected void seekInternal(long pos) {} 228 229 230 public void close() {} 231 232 public long length() { 233 return length; 234 } 235 236 237 } 238 239 } 240 | Popular Tags |