1 52 53 package com.go.trove.io; 54 55 import java.io.OutputStream ; 56 import java.io.IOException ; 57 import java.util.List ; 58 import java.util.ArrayList ; 59 60 69 public class SpilloverByteBuffer implements ByteBuffer { 70 private Group mGroup; 71 72 private ByteBuffer mLocalBuffer; 73 private ByteBuffer mSpillover; 74 75 private List mCaptureBuffers; 76 77 84 public SpilloverByteBuffer(Group group) { 85 mGroup = group; 86 mLocalBuffer = new DefaultByteBuffer(); 87 } 88 89 public long getBaseByteCount() throws IOException { 90 if (mSpillover == null) { 91 return mLocalBuffer.getBaseByteCount(); 92 } 93 else { 94 return mSpillover.getBaseByteCount(); 95 } 96 } 97 98 public long getByteCount() throws IOException { 99 if (mSpillover == null) { 100 return mLocalBuffer.getByteCount(); 101 } 102 else { 103 return mSpillover.getByteCount(); 104 } 105 } 106 107 public void writeTo(OutputStream out) throws IOException { 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 { 117 List 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 { 137 append(bytes, 0, bytes.length); 138 } 139 140 public void append(byte[] bytes, int offset, int length) 141 throws IOException 142 { 143 List 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 { 164 if (s == null) { 165 return; 166 } 167 168 List 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 captureBuffers; 186 if ((captureBuffers = mCaptureBuffers) == null) { 187 captureBuffers = mCaptureBuffers = new ArrayList (); 188 } 189 captureBuffers.add(buffer); 190 } 191 192 public void removeCaptureBuffer(ByteBuffer buffer) { 193 List captureBuffers; 194 if ((captureBuffers = mCaptureBuffers) != null) { 195 captureBuffers.remove(buffer); 196 } 197 } 198 199 public void reset() throws IOException { 200 mLocalBuffer.reset(); 201 if (mSpillover != null) { 202 mSpillover.reset(); 203 } 204 205 List 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 { 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 { 223 mSpillover = mGroup.createFileByteBuffer(); 224 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 ; 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 |