1 package org.jacorb.orb; 2 21 22 import java.util.*; 23 24 import org.apache.avalon.framework.configuration.*; 25 26 import org.omg.CORBA.NO_MEMORY ; 27 import org.omg.CORBA.BAD_INV_ORDER ; 28 29 41 42 public final class BufferManager 43 { 44 45 private List[] bufferPool; 46 private byte[] bufferMax = null; 48 49 51 52 private static int MAX; 53 54 58 59 private static final int MIN_OFFSET = 5; 60 61 62 63 private static final int THRESHOLD = 20; 64 private static final int MEM_BUFSIZE = 256; 65 private static final int MIN_PREFERRED_BUFS = 10; 66 67 private Reaper reaper; 69 70 76 private static int time = 0; 77 78 79 private static BufferManager singleton = new BufferManager(); 80 81 private static boolean configured = false; 82 83 87 public static void configure(Configuration configuration) 88 throws ConfigurationException 89 { 90 singleton.singletonConfigure(configuration); 91 configured = true; 92 } 93 94 private BufferManager() 95 { 96 } 97 98 101 102 private void singletonConfigure(Configuration configuration) 103 throws ConfigurationException 104 { 105 time = 106 configuration.getAttributeAsInteger("jacorb.bufferManagerMaxFlush", 0); 107 108 MAX = 109 configuration.getAttributeAsInteger("jacorb.maxManagedBufSize", 18); 110 111 bufferPool = new List[ MAX ]; 112 113 for( int i = 0; i < MAX; i++) 114 { 115 bufferPool[ i ] = new ArrayList(); 116 } 117 118 120 121 int m_pos = 0; 122 int j = MEM_BUFSIZE; 123 124 while( j > 1 ) 125 { 126 j = j >> 1; 127 m_pos++; 128 } 129 for( int min = 0; min < MIN_PREFERRED_BUFS; min++ ) 130 { 131 bufferPool[ m_pos -MIN_OFFSET ].add(new byte[ MEM_BUFSIZE ]); 132 } 133 134 if (time > 0) 135 { 136 reaper = new Reaper (time); 138 reaper.setName ("BufferManager MaxCache Reaper"); 139 reaper.setDaemon (true); 140 reaper.start(); 141 } 142 } 143 144 148 149 public static BufferManager getInstance() 150 throws BAD_INV_ORDER 151 { 152 if (!configured) 153 throw new BAD_INV_ORDER ("Buffer Manager not configured"); 154 return singleton; 155 } 156 157 160 161 private static final int log2up(int n) 162 { 163 int l =0; 164 int nn = n-1; 165 while( (nn >>l) != 0 ) 166 l++; 167 168 return l; 169 } 170 171 172 175 176 private static final int log2down(int n) 177 { 178 int l =0; 179 int nn = n; 180 while( (nn >>l) != 0 ) 181 l++; 182 183 return l-1; 184 } 185 186 187 public byte[] getPreferredMemoryBuffer() 188 { 189 return getBuffer( MEM_BUFSIZE ); 190 } 191 192 193 public synchronized byte[] getBuffer( int initial ) 194 { 195 return getBuffer(initial, false); 196 } 197 198 199 207 208 public synchronized byte[] getBuffer( int initial, boolean cdrStr ) 209 { 210 byte [] result; 211 List s; 212 213 int log = log2up(initial); 214 215 if (log >= MAX) 216 { 217 try 218 { 219 if (cdrStr==false || time < 0) 220 { 221 result = new byte[initial]; 223 } 224 else 225 { 226 if (bufferMax == null || bufferMax.length < initial) 228 { 229 bufferMax = new byte[initial*2]; 231 } 232 result = bufferMax; 234 bufferMax = null; 235 } 236 } 237 catch (OutOfMemoryError e) 238 { 239 throw new NO_MEMORY (); 240 } 241 } 242 else 243 { 244 s = bufferPool[log > MIN_OFFSET ? log-MIN_OFFSET : 0 ]; 245 246 if(!s.isEmpty()) 247 { 248 result = (byte[])s.remove(s.size()-1); 250 } 251 else 252 { 253 result = new byte[log > MIN_OFFSET ? 1<<log : 1 << MIN_OFFSET ]; 254 } 255 } 256 return result; 257 } 258 259 public synchronized void returnBuffer(byte[] current) 260 { 261 returnBuffer (current, false); 262 } 263 264 265 272 synchronized void returnBuffer(byte[] current, boolean cdrStr) 273 { 274 if (current != null) 275 { 276 int log_curr = log2down(current.length); 277 278 if( log_curr >= MIN_OFFSET ) 279 { 280 if( log_curr > MAX ) 281 { 282 if (cdrStr==true && 285 (time >= 0 && 286 (bufferMax == null || bufferMax.length < current.length))) 287 { 288 bufferMax = current; 289 } 290 return; 291 } 292 293 List s = bufferPool[ log_curr-MIN_OFFSET ]; 294 if( s.size() < THRESHOLD ) 295 { 296 s.add( current ); 297 } 298 } 299 } 300 } 301 302 public void release() 303 { 304 for( int i= MAX; i > 0; ) 306 { 307 i--; 308 bufferPool[i].clear(); 309 } 310 if (reaper != null) 311 { 312 reaper.done = true; 313 reaper.wake(); 314 } 315 } 316 317 318 private class Reaper extends Thread 319 { 320 public boolean done = false; 321 private int sleepInterval = 0; 322 323 public Reaper (int sleepInterval) 324 { 325 this.sleepInterval = (sleepInterval * 1000); 327 } 328 329 public void run() 330 { 331 long time; 332 333 while (true) 334 { 335 337 try 338 { 339 time = sleepInterval + System.currentTimeMillis(); 340 do 341 { 342 sleep (sleepInterval); 343 } 344 while (System.currentTimeMillis() <= time); 345 } 346 catch (InterruptedException ex) {} 347 348 350 if (done) 351 { 352 break; 353 } 354 355 bufferMax = null; 365 } 366 } 367 368 public synchronized void wake() 369 { 370 notify(); 372 } 373 } 374 } 375 | Popular Tags |