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.io.*;
026:import java.util.*;
027:import org.artsProject.mcop.*;
028:
029:public class Handles<T implements Handled<T>> {
030: ChunkManager cm;
031: MarDemar<T> md;
032: ArrayList<HandleImpl> handles = new ArrayList<HandleImpl>();
033: ChunkRef master;
034: int firstEmptyHandle = 0;
035:
036: class HandleImpl implements Handle<T> {
037: int index;
038: T t;
039: ChunkRef chunk;
040:
041: HandleImpl(T t, int index) {
042: this .t = t;
043: this .index = index;
044: t.setHandle(this );
045: }
046:
047: HandleImpl(ChunkRef chunk, int index) {
048: this .chunk = chunk;
049: this .index = index;
050: }
051:
052: public T get() {
053: if (t == null) {
054: t = md.read(cm.readChunk(chunk));
055: t.setHandle(this );
056: }
057: return t;
058: }
059:
060: public void marshal(Buffer b) {
061: b.writeLong(index);
062: }
063:
064: ChunkRef getChunk() {
065: if (chunk == null) {
066: Buffer b = new Buffer();
067: md.marshal(b, t);
068: chunk = cm.createChunk(b);
069: }
070: return chunk;
071: }
072:
073: public void set(T t) {
074: this .t = t;
075: chunk = null;
076: master = null;
077: t.setHandle(this );
078: }
079:
080: public void dispose() {
081: if (t != null)
082: t.setHandle(null);
083: handles.set(index, null);
084: if (firstEmptyHandle > index) firstEmptyHandle = index;
085: while (handles.size() != 0 && handles.get(handles.size()-1) == null)
086: handles.remove(handles.size()-1);
087: if (firstEmptyHandle > handles.size()) firstEmptyHandle = handles.size();
088: master = null;
089: }
090:
091: public void invalidate() {
092: chunk = null;
093: master = null;
094: }
095: }
096:
097: public Handles(ChunkManager cm, MarDemar<T> md) {
098: this .cm = cm;
099: this .md = md;
100: }
101:
102: public Handles(ChunkManager cm, MarDemar<T> md, ChunkRef chunk) {
103: this (cm, md);
104: Buffer b = cm.readChunk(master = chunk);
105: int n = b.readLong();
106: for (int i = 0; i < n; i++) {
107: ChunkRef c = new ChunkRef(b);
108: if (c.index != 0)
109: handles.add(new HandleImpl(c, i));
110: else
111: handles.add(null);
112: }
113: }
114:
115: public Handle<T> add(T t) {
116: int i;
117: for (i = firstEmptyHandle; i < handles.size(); i++)
118: if (handles.get(i) == null)
119: break;
120: firstEmptyHandle = i+1;
121: HandleImpl s = new HandleImpl(t, i);
122: if (i < handles.size())
123: handles.set(i, s);
124: else
125: handles.add(s);
126: master = null;
127: return s;
128: }
129:
130: public Handle<T> read(Buffer b) {
131: HandleImpl h = handles.get(b.readLong());
132: if (h == null)
133: throw new RuntimeException("Handle was disposed");
134: return h;
135: }
136:
137: public ChunkRef flush() {
138: if (master == null) {
139: Buffer b = new Buffer();
140: b.writeLong(handles.size());
141: for (int i = 0; i < handles.size(); i++) {
142: HandleImpl h = handles.get(i);
143: if (h != null)
144: h.getChunk().writeType(b);
145: else
146: ChunkManager.NULLCHUNK.writeType(b);
147: }
148: master = cm.createChunk(b);
149: }
150: return master;
151: }
152:
153: public void collectChunks(BitSet whiteList) {
154: for (int i = 0; i < handles.size(); i++) {
155: HandleImpl h = handles.get(i);
156: if (h != null) {
157: ChunkRef chunk = handles.get(i).chunk;
158: if (chunk != null)
159: whiteList.set(chunk.index);
160: }
161: }
162: if (master != null)
163: whiteList.set(master.index);
164: }
165:
166: public Handle<T> fixedIndex(int index) {
167: return handles.get(index);
168: }
169:}
|