⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 directbytebufferpoolreal.java

📁 java 文件下载器。可自定义
💻 JAVA
字号:
// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   DirectByteBufferPoolReal.java

package org.gudy.azureus2.core3.util;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.*;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.logging.LogAlert;
import org.gudy.azureus2.core3.logging.Logger;

// Referenced classes of package org.gudy.azureus2.core3.util:
//			DirectByteBufferPool, Debug, DirectByteBuffer, SimpleTimer, 
//			TimerEventPerformer, TimerEvent

public class DirectByteBufferPoolReal extends DirectByteBufferPool
{
	private static class myInteger
	{

		int value;

		private myInteger()
		{
		}
	}

	private static class sliceBuffer
	{

		private ByteBuffer buffer;
		private short alloc_id;
		private short slice_id;

		protected ByteBuffer getBuffer()
		{
			return buffer;
		}

		protected short getAllocID()
		{
			return alloc_id;
		}

		protected short getSliceID()
		{
			return slice_id;
		}

		protected sliceBuffer(ByteBuffer _buffer, short _alloc_id, short _slice_id)
		{
			buffer = _buffer;
			alloc_id = _alloc_id;
			slice_id = _slice_id;
		}
	}

	private static class sliceDBB extends DirectByteBuffer
	{

		private sliceBuffer slice_buffer;

		protected sliceBuffer getSliceBuffer()
		{
			return slice_buffer;
		}

		protected sliceDBB(byte _allocator, sliceBuffer _sb)
		{
			super(_allocator, _sb.getBuffer(), DirectByteBufferPoolReal.pool);
			slice_buffer = _sb;
		}
	}


	protected static final boolean DEBUG_TRACK_HANDEDOUT = false;
	protected static final boolean DEBUG_PRINT_MEM = false;
	protected static final int DEBUG_PRINT_TIME = 0x1d4c0;
	protected static final boolean DEBUG_HANDOUT_SIZES = false;
	protected static final boolean DEBUG_FREE_SIZES = false;
	private static final int START_POWER = 12;
	private static final int END_POWER = 25;
	private static final int EXTRA_BUCKETS[] = {
		16512
	};
	public static final int MAX_SIZE = BigInteger.valueOf(2L).pow(25).intValue();
	private static final DirectByteBufferPoolReal pool = new DirectByteBufferPoolReal();
	private final Map buffersMap = new LinkedHashMap(14);
	private final Object poolsLock = new Object();
	private static final int SLICE_END_SIZE = 2048;
	private static final int SLICE_ALLOC_CHUNK_SIZE = 4096;
	private static final short SLICE_ENTRY_SIZES[] = {
		8, 16, 32, 64, 128, 256, 512, 1024, 2048
	};
	private static final short SLICE_ALLOC_MAXS[] = {
		256, 256, 128, 64, 64, 64, 64, 64, 64
	};
	private static final short SLICE_ENTRY_ALLOC_SIZES[];
	private static final List slice_entries[];
	private static final boolean slice_allocs[][];
	private static final boolean slice_alloc_fails[] = new boolean[SLICE_ENTRY_SIZES.length];
	private static final long slice_use_count[] = new long[SLICE_ENTRY_SIZES.length];
	private final Map handed_out = new IdentityHashMap();
	private final Map size_counts = new TreeMap();
	private static final long COMPACTION_CHECK_PERIOD = 0x1d4c0L;
	private static final long MAX_FREE_BYTES = 0xa00000L;
	private static final long MIN_FREE_BYTES = 0x100000L;
	private long bytesIn;
	private long bytesOut;

	protected DirectByteBufferPoolReal()
	{
		bytesIn = 0L;
		bytesOut = 0L;
		ArrayList list = new ArrayList();
		for (int p = 12; p <= 25; p++)
			list.add(new Integer(BigInteger.valueOf(2L).pow(p).intValue()));

		for (int i = 0; i < EXTRA_BUCKETS.length; i++)
			list.add(new Integer(EXTRA_BUCKETS[i]));

		Integer sizes[] = new Integer[list.size()];
		list.toArray(sizes);
		Arrays.sort(sizes);
		for (int i = 0; i < sizes.length; i++)
		{
			ArrayList bufferPool = new ArrayList();
			buffersMap.put(sizes[i], bufferPool);
		}

		SimpleTimer.addPeriodicEvent("DirectBB:compact", 0x1d4c0L, new TimerEventPerformer() {

			final DirectByteBufferPoolReal this$0;

			public void perform(TimerEvent ev)
			{
				compactBuffers();
			}

			
			{
				this$0 = DirectByteBufferPoolReal.this;
				super();
			}
		});
	}

	private ByteBuffer allocateNewBuffer(int _size)
	{
		return ByteBuffer.allocateDirect(_size);
		OutOfMemoryError e;
		e;
		clearBufferPools();
		runGarbageCollection();
		return ByteBuffer.allocateDirect(_size);
		OutOfMemoryError ex;
		ex;
		String msg = "Memory allocation failed: Out of direct memory space.\nTo fix: Use the -XX:MaxDirectMemorySize=512m command line option,\nor upgrade your Java JRE to version 1.4.2_05 or 1.5 series or newer.";
		Debug.out(msg);
		Logger.log(new LogAlert(false, 3, msg));
		printInUse(true);
		throw ex;
	}

	protected DirectByteBuffer getBufferSupport(byte _allocator, int _length)
	{
		if (_length < 1)
		{
			Debug.out((new StringBuilder()).append("requested length [").append(_length).append("] < 1").toString());
			return null;
		}
		if (_length > MAX_SIZE)
		{
			Debug.out((new StringBuilder()).append("requested length [").append(_length).append("] > MAX_SIZE [").append(MAX_SIZE).append("]").toString());
			return null;
		} else
		{
			return pool.getBufferHelper(_allocator, _length);
		}
	}

	private DirectByteBuffer getBufferHelper(byte _allocator, int _length)
	{
		DirectByteBuffer res;
		ByteBuffer buff;
		if (_length <= 2048)
		{
			res = getSliceBuffer(_allocator, _length);
		} else
		{
			buff = null;
			Integer reqVal = new Integer(_length);
			Iterator it = buffersMap.keySet().iterator();
			do
			{
				if (!it.hasNext())
					break;
				Integer keyVal = (Integer)it.next();
				if (reqVal.compareTo(keyVal) > 0)
					continue;
				ArrayList bufferPool = (ArrayList)buffersMap.get(keyVal);
				synchronized (poolsLock)
				{
					if (bufferPool.isEmpty())
						buff = allocateNewBuffer(keyVal.intValue());
					else
						synchronized (bufferPool)
						{
							buff = (ByteBuffer)bufferPool.remove(bufferPool.size() - 1);
						}
				}
				break;
			} while (true);
			if (buff == null)
			{
				Debug.out("Unable to find an appropriate buffer pool");
				throw new RuntimeException("Unable to find an appropriate buffer pool");
			}
			res = new DirectByteBuffer(_allocator, buff, this);
		}
		buff = res.getBufferInternal();
		buff.clear();
		buff.limit(_length);
		bytesOut += buff.capacity();
		return res;
	}

	protected void returnBufferSupport(DirectByteBuffer ddb)
	{
		ByteBuffer buff = ddb.getBufferInternal();
		int capacity = buff.capacity();
		bytesIn += capacity;
		if (capacity <= 2048)
		{
			freeSliceBuffer(ddb);
		} else
		{
			Integer buffSize = new Integer(capacity);
			ArrayList bufferPool = (ArrayList)buffersMap.get(buffSize);
			if (bufferPool != null)
				synchronized (bufferPool)
				{
					bufferPool.add(buff);
				}
			else
				Debug.out("Invalid buffer given; could not find proper buffer pool");
		}
	}

	private void clearBufferPools()
	{
		ArrayList bufferPool;
		for (Iterator it = buffersMap.values().iterator(); it.hasNext(); bufferPool.clear())
			bufferPool = (ArrayList)it.next();

	}

	private void runGarbageCollection()
	{
		System.runFinalization();
		System.gc();
	}

	private void compactBuffers()
	{
		long freeSize;
label0:
		{
			synchronized (poolsLock)
			{
				freeSize = bytesFree();
				if (freeSize >= 0x100000L)
					break label0;
			}
			break MISSING_BLOCK_LABEL_163;
		}
		float remainingFactor;
		if (freeSize > 0xa00000L)
			remainingFactor = 5242880F / (float)freeSize;
		else
			remainingFactor = 1.0F - (0.5F * (float)freeSize) / 1.048576E+007F;
		ArrayList pools = new ArrayList(buffersMap.values());
		for (int i = pools.size() - 1; i >= 0; i--)
		{
			ArrayList pool = (ArrayList)pools.get(i);
			int limit = (int)((float)pool.size() * remainingFactor);
			for (int j = pool.size() - 1; j >= limit; j--)
				pool.remove(j);

		}

		runGarbageCollection();
		obj;
		JVM INSTR monitorexit ;
		break MISSING_BLOCK_LABEL_163;
		exception;
		throw exception;
		compactSlices();
		return;
	}

	private long bytesFree()
	{
		long bytesUsed = 0L;
		synchronized (poolsLock)
		{
			for (Iterator it = buffersMap.keySet().iterator(); it.hasNext();)
			{
				Integer keyVal = (Integer)it.next();
				ArrayList bufferPool = (ArrayList)buffersMap.get(keyVal);
				bytesUsed += keyVal.intValue() * bufferPool.size();
			}

		}
		return bytesUsed;
	}

	private void printInUse(boolean flag)
	{
	}

	private DirectByteBuffer getSliceBuffer(byte _allocator, int _length)
	{
		int slice_index = getSliceIndex(_length);
		List my_slice_entries = slice_entries[slice_index];
		List list = my_slice_entries;
		JVM INSTR monitorenter ;
		sliceBuffer sb;
		ByteBuffer buff;
		boolean my_allocs[] = slice_allocs[slice_index];
		sb = null;
		if (my_slice_entries.size() > 0)
		{
			sb = (sliceBuffer)my_slice_entries.remove(0);
			slice_use_count[slice_index]++;
			break MISSING_BLOCK_LABEL_305;
		}
		short slot = -1;
		short i = 0;
		do
		{
			if (i >= my_allocs.length)
				break;
			if (!my_allocs[i])
			{
				slot = i;
				break;
			}
			i++;
		} while (true);
		if (slot != -1)
		{
			short slice_entry_size = SLICE_ENTRY_SIZES[slice_index];
			short slice_entry_count = SLICE_ENTRY_ALLOC_SIZES[slice_index];
			ByteBuffer chunk = ByteBuffer.allocateDirect(slice_entry_size * slice_entry_count);
			my_allocs[slot] = true;
			for (short i = 0; i < slice_entry_count; i++)
			{
				chunk.limit((i + 1) * slice_entry_size);
				chunk.position(i * slice_entry_size);
				ByteBuffer slice = chunk.slice();
				sliceBuffer new_buffer = new sliceBuffer(slice, slot, i);
				if (i == 0)
				{
					sb = new_buffer;
					slice_use_count[slice_index]++;
				} else
				{
					my_slice_entries.add(new_buffer);
				}
			}

			break MISSING_BLOCK_LABEL_305;
		}
		if (!slice_alloc_fails[slice_index])
		{
			slice_alloc_fails[slice_index] = true;
			Debug.out((new StringBuilder()).append("Run out of slice space for '").append(SLICE_ENTRY_SIZES[slice_index]).append(", reverting to normal allocation").toString());
		}
		buff = ByteBuffer.allocate(_length);
		return new DirectByteBuffer(_allocator, buff, this);
		sliceDBB dbb = new sliceDBB(_allocator, sb);
		dbb;
		list;
		JVM INSTR monitorexit ;
		return;
		Exception exception;
		exception;
		throw exception;
	}

	private void freeSliceBuffer(DirectByteBuffer ddb)
	{
		if (ddb instanceof sliceDBB)
		{
			int slice_index = getSliceIndex(ddb.getBufferInternal().capacity());
			List my_slice_entries = slice_entries[slice_index];
			synchronized (my_slice_entries)
			{
				my_slice_entries.add(0, ((sliceDBB)ddb).getSliceBuffer());
			}
		}
	}

	private void compactSlices()
	{
		for (int i = 0; i < slice_entries.length; i++)
		{
			int entries_per_alloc = SLICE_ENTRY_ALLOC_SIZES[i];
			List l = slice_entries[i];
			if (l.size() < entries_per_alloc)
				continue;
			synchronized (l)
			{
				Collections.sort(l, new Comparator() {

					final DirectByteBufferPoolReal this$0;

					public int compare(Object o1, Object o2)
					{
						sliceBuffer sb1 = (sliceBuffer)o1;
						sliceBuffer sb2 = (sliceBuffer)o2;
						int res = sb1.getAllocID() - sb2.getAllocID();
						if (res == 0)
							res = sb1.getSliceID() - sb2.getSliceID();
						return res;
					}

			
			{
				this$0 = DirectByteBufferPoolReal.this;
				super();
			}
				});
				boolean allocs[] = slice_allocs[i];
				Iterator it = l.iterator();
				int current_alloc = -1;
				int entry_count = 0;
				boolean freed_one = false;
				while (it.hasNext()) 
				{
					sliceBuffer sb = (sliceBuffer)it.next();
					int aid = sb.getAllocID();
					if (aid != current_alloc)
					{
						if (entry_count == entries_per_alloc)
						{
							freed_one = true;
							allocs[aid] = false;
						}
						current_alloc = aid;
						entry_count = 1;
					} else
					{
						entry_count++;
					}
				}
				if (entry_count == entries_per_alloc)
				{
					freed_one = true;
					allocs[current_alloc] = false;
				}
				if (freed_one)
				{
					it = l.iterator();
					do
					{
						if (!it.hasNext())
							break;
						sliceBuffer sb = (sliceBuffer)it.next();
						if (!allocs[sb.getAllocID()])
							it.remove();
					} while (true);
				}
			}
		}

	}

	private int getSliceIndex(int _length)
	{
		for (int i = 0; i < SLICE_ENTRY_SIZES.length; i++)
			if (_length <= SLICE_ENTRY_SIZES[i])
				return i;

		Debug.out("eh?");
		return 0;
	}

	static 
	{
		SLICE_ENTRY_ALLOC_SIZES = new short[SLICE_ENTRY_SIZES.length];
		slice_entries = new List[SLICE_ENTRY_SIZES.length];
		slice_allocs = new boolean[SLICE_ENTRY_SIZES.length][];
		int mult = COConfigurationManager.getIntParameter("memory.slice.limit.multiplier");
		if (mult > 1)
		{
			for (int i = 0; i < SLICE_ALLOC_MAXS.length; i++)
				SLICE_ALLOC_MAXS[i] *= mult;

		}
		for (int i = 0; i < SLICE_ENTRY_SIZES.length; i++)
		{
			SLICE_ENTRY_ALLOC_SIZES[i] = (short)(4096 / SLICE_ENTRY_SIZES[i]);
			slice_allocs[i] = new boolean[SLICE_ALLOC_MAXS[i]];
			slice_entries[i] = new LinkedList();
		}

	}


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -