001: /*
002: This source file is part of Smyle, a database library.
003: For up-to-date information, see http://www.drjava.de/smyle
004: Copyright (C) 2001 Stefan Reich (doc@drjava.de)
005:
006: This library is free software; you can redistribute it and/or
007: modify it under the terms of the GNU Lesser General Public
008: License as published by the Free Software Foundation; either
009: version 2.1 of the License, or (at your option) any later version.
010:
011: This library is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public
017: License along with this library; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019:
020: For full license text, see doc/license/lgpl.txt in this distribution
021: */
022:
023: package drjava.smyle.core;
024:
025: import java.util.*;
026: import java.io.*;
027: import com.go.trove.util.*;
028: import org.artsProject.mcop.*;
029: import drjava.smyle.*;
030:
031: /** read-only ChunkManager for converting legacy Smyle 0.2.5/0.3 beta databases */
032: public class ChunkManager025 extends MasterChunkManager {
033: static final int DEFAULT_NATURALFILESIZE = 64 * 1024,
034: MAXCACHESIZE = DEFAULT_NATURALFILESIZE;
035:
036: static final boolean debug = false;
037:
038: Disk disk;
039: ArrayList<Chunk> chunks = new ArrayList<Chunk>();
040: boolean masterLoaded = false;
041: ChunkRef masterChunk = NULLCHUNK;
042: Cache<Long, byte[]> fileCache = new Cache<Long, byte[]>(1);
043:
044: public ChunkManager025(Disk disk) {
045: this .disk = disk;
046: }
047:
048: // accessors
049:
050: public synchronized Buffer readChunk(int index) {
051: try {
052: if (index <= 0)
053: throw new IllegalArgumentException(
054: "Invalid ChunkRef (index=" + index + ")");
055: Chunk chunk = chunks.get(index - 1);
056: if (chunk.file == 0) {
057: throw new InternalSmyleError("Chunk " + index
058: + " doesn't exist anymore");
059: } else {
060: // look in cache
061: Long lFile = new Long(chunk.file);
062: byte[] data = fileCache.get(lFile);
063: if (data != null)
064: return new Buffer(data, chunk.offset, chunk.length);
065:
066: // read chunk from file
067: DataInputStream in = new DataInputStream(disk
068: .readFile(chunk.file));
069:
070: // store in cache if cacheable
071: int fileLen = disk.getFileLength(chunk.file);
072: if (fileLen <= MAXCACHESIZE) {
073: data = new byte[fileLen];
074: in.readFully(data);
075: in.close();
076: fileCache.put(lFile, data);
077: return new Buffer(data, chunk.offset, chunk.length);
078: } else {
079: // Not cacheable
080: in.skip(chunk.offset);
081: data = new byte[chunk.length];
082: in.readFully(data);
083: in.close();
084: return new Buffer(data);
085: }
086: }
087: } catch (IOException e) {
088: throw new SmyleIOException(e);
089: }
090: }
091:
092: public synchronized ChunkRef getMasterChunk() {
093: if (!masterLoaded) {
094: masterLoaded = true;
095: loadMaster();
096: }
097: return masterChunk;
098: }
099:
100: // mutators
101:
102: public synchronized ChunkRef createChunk(Buffer data) {
103: throw new RuntimeException(
104: "This is a legacy chunk manager; read only");
105: }
106:
107: void loadMaster() {
108: long master = disk.getMasterFile();
109: if (master != 0) {
110: Buffer b = DiskUtil.fileToBuffer(disk, master);
111: b.readLong(); // version
112: chunks.clear();
113: MCOP.readSeq(b, chunks, Chunk.DEMARSHALLER);
114: masterChunk = new ChunkRef(b);
115: }
116: }
117:
118: public synchronized ChunkRef createMasterChunk(Buffer data) {
119: throw new RuntimeException(
120: "This is a legacy chunk manager; read only");
121: }
122:
123: public synchronized void deleteEverythingBut(BitSet whiteList) {
124: throw new RuntimeException(
125: "This is a legacy chunk manager; read only");
126: }
127: }
|