KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > go > trove > io > SpilloverByteBuffer


1 /* ====================================================================
2  * Trove - Copyright (c) 1999-2000 Walt Disney Internet Group
3  * ====================================================================
4  * The Tea Software License, Version 1.1
5  *
6  * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Walt Disney Internet Group (http://opensource.go.com/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact opensource@dig.com.
31  *
32  * 5. Products derived from this software may not be called "Tea",
33  * "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
34  * "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
35  * written permission of the Walt Disney Internet Group.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
41  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
43  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
44  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * For more information about Tea, please see http://opensource.go.com/.
51  */

52
53 package com.go.trove.io;
54
55 import java.io.OutputStream JavaDoc;
56 import java.io.IOException JavaDoc;
57 import java.util.List JavaDoc;
58 import java.util.ArrayList JavaDoc;
59
60 /******************************************************************************
61  * A ByteBuffer implementation that initially stores its data in a
62  * DefaultByteBuffer, but after a certain threshold is reached, spills over
63  * into a FileByteBuffer.
64  *
65  * @author Brian S O'Neill
66  * @version
67  * <!--$$Revision:--> 16 <!-- $-->, <!--$$JustDate:--> 00/12/05 <!-- $-->
68  */

69 public class SpilloverByteBuffer implements ByteBuffer {
70     private Group mGroup;
71     
72     private ByteBuffer mLocalBuffer;
73     private ByteBuffer mSpillover;
74
75     private List JavaDoc mCaptureBuffers;
76
77     /**
78      * Create a SpilloverByteBuffer against a Group that sets the threshold
79      * and can create a spillover FileByteBuffer. The Group can be shared
80      * among many SpilloverByteBuffers.
81      *
82      * @param group a group that can be shared among many SpilloverByteBuffers
83      */

84     public SpilloverByteBuffer(Group group) {
85         mGroup = group;
86         mLocalBuffer = new DefaultByteBuffer();
87     }
88
89     public long getBaseByteCount() throws IOException JavaDoc {
90         if (mSpillover == null) {
91             return mLocalBuffer.getBaseByteCount();
92         }
93         else {
94             return mSpillover.getBaseByteCount();
95         }
96     }
97
98     public long getByteCount() throws IOException JavaDoc {
99         if (mSpillover == null) {
100             return mLocalBuffer.getByteCount();
101         }
102         else {
103             return mSpillover.getByteCount();
104         }
105     }
106
107     public void writeTo(OutputStream JavaDoc out) throws IOException JavaDoc {
108         if (mSpillover == null) {
109             mLocalBuffer.writeTo(out);
110         }
111         else {
112             mSpillover.writeTo(out);
113         }
114     }
115
116     public void append(byte b) throws IOException JavaDoc {
117         List JavaDoc captureBuffers;
118         if ((captureBuffers = mCaptureBuffers) != null) {
119             int size = captureBuffers.size();
120             for (int i=0; i<size; i++) {
121                 ((ByteBuffer)captureBuffers.get(i)).append(b);
122             }
123         }
124
125         if (mSpillover == null) {
126             if (mGroup.adjustLevel(1)) {
127                 mLocalBuffer.append(b);
128                 return;
129             }
130             spillover();
131         }
132
133         mSpillover.append(b);
134     }
135
136     public void append(byte[] bytes) throws IOException JavaDoc {
137         append(bytes, 0, bytes.length);
138     }
139
140     public void append(byte[] bytes, int offset, int length)
141         throws IOException JavaDoc
142     {
143         List JavaDoc captureBuffers;
144         if ((captureBuffers = mCaptureBuffers) != null) {
145             int size = captureBuffers.size();
146             for (int i=0; i<size; i++) {
147                 ((ByteBuffer)captureBuffers.get(i)).append
148                     (bytes, offset, length);
149             }
150         }
151
152         if (mSpillover == null) {
153             if (mGroup.adjustLevel(length)) {
154                 mLocalBuffer.append(bytes, offset, length);
155                 return;
156             }
157             spillover();
158         }
159
160         mSpillover.append(bytes, offset, length);
161     }
162
163     public void appendSurrogate(ByteData s) throws IOException JavaDoc {
164         if (s == null) {
165             return;
166         }
167
168         List JavaDoc captureBuffers;
169         if ((captureBuffers = mCaptureBuffers) != null) {
170             int size = captureBuffers.size();
171             for (int i=0; i<size; i++) {
172                 ((ByteBuffer)captureBuffers.get(i)).appendSurrogate(s);
173             }
174         }
175
176         if (mSpillover == null) {
177             mLocalBuffer.appendSurrogate(s);
178         }
179         else {
180             mSpillover.appendSurrogate(s);
181         }
182     }
183
184     public void addCaptureBuffer(ByteBuffer buffer) {
185         List JavaDoc captureBuffers;
186         if ((captureBuffers = mCaptureBuffers) == null) {
187             captureBuffers = mCaptureBuffers = new ArrayList JavaDoc();
188         }
189         captureBuffers.add(buffer);
190     }
191
192     public void removeCaptureBuffer(ByteBuffer buffer) {
193         List JavaDoc captureBuffers;
194         if ((captureBuffers = mCaptureBuffers) != null) {
195             captureBuffers.remove(buffer);
196         }
197     }
198
199     public void reset() throws IOException JavaDoc {
200         mLocalBuffer.reset();
201         if (mSpillover != null) {
202             mSpillover.reset();
203         }
204         
205         List JavaDoc captureBuffers;
206         if ((captureBuffers = mCaptureBuffers) != null) {
207             int size = captureBuffers.size();
208             for (int i=0; i<size; i++) {
209                 ((ByteData)captureBuffers.get(i)).reset();
210             }
211         }
212     }
213
214     protected void finalize() throws IOException JavaDoc {
215         if (mLocalBuffer != null) {
216             long count = mLocalBuffer.getBaseByteCount();
217             mLocalBuffer = null;
218             mGroup.adjustLevel(-count);
219         }
220     }
221
222     private void spillover() throws IOException JavaDoc {
223         mSpillover = mGroup.createFileByteBuffer();
224         // TODO: This is bad! By writing out the contents of the existing
225
// buffer early, surrogates are evaluated too soon!
226
mLocalBuffer.writeTo(new ByteBufferOutputStream(mSpillover));
227
228         long count = mLocalBuffer.getBaseByteCount();
229         mLocalBuffer = null;
230         mGroup.adjustLevel(-count);
231     }
232
233     public static abstract class Group {
234         private final long mThreshold;
235         private long mLevel;
236
237         public Group(long threshold) {
238             mThreshold = threshold;
239         }
240
241         public final long getThreshold() {
242             return mThreshold;
243         }
244
245         public final synchronized long getCurrentLevel() {
246             return mLevel;
247         }
248
249         public abstract FileByteBuffer createFileByteBuffer()
250             throws IOException JavaDoc;
251
252         synchronized boolean adjustLevel(long delta) {
253             long newLevel;
254             if ((newLevel = mLevel + delta) > mThreshold) {
255                 return false;
256             }
257             else {
258                 if (newLevel < 0) {
259                     newLevel = 0;
260                 }
261                 mLevel = newLevel;
262                 return true;
263             }
264         }
265     }
266 }
267
Popular Tags