/// <summary>Recycle the given byte array.</summary> /// <remarks> /// Recycle the given byte array. /// The byte array may or may not be allocated /// by the /// <see cref="NewByteArray(int)"/> /// method. /// This is a non-blocking call. /// </remarks> public override int Release(byte[] array) { Preconditions.CheckNotNull(array); if (Log.IsDebugEnabled()) { debugMessage.Get().Append("recycle: array.length=").Append(array.Length); } int freeQueueSize; if (array.Length == 0) { freeQueueSize = -1; } else { ByteArrayManager.FixedLengthManager manager = managers.Get(array.Length, false); freeQueueSize = manager == null ? -1 : manager.Recycle(array); } if (Log.IsDebugEnabled()) { debugMessage.Get().Append(", freeQueueSize=").Append(freeQueueSize); LogDebugMessage(); } return(freeQueueSize); }
/// <summary> /// Allocate a byte array, where the length of the allocated array /// is the least power of two of the given length /// unless the given length is less than /// <see cref="ByteArrayManager.MinArrayLength"/> /// . /// In such case, the returned array length is equal to /// <see cref="ByteArrayManager.MinArrayLength"/> /// . /// If the number of allocated arrays exceeds the capacity, /// the current thread is blocked until /// the number of allocated arrays drops to below the capacity. /// The byte array allocated by this method must be returned for recycling /// via the /// <see cref="Release(byte[])"/> /// method. /// </summary> /// <returns>a byte array with length larger than or equal to the given length.</returns> /// <exception cref="System.Exception"/> public override byte[] NewByteArray(int arrayLength) { Preconditions.CheckArgument(arrayLength >= 0); if (Log.IsDebugEnabled()) { debugMessage.Get().Append("allocate(").Append(arrayLength).Append(")"); } byte[] array; if (arrayLength == 0) { array = EmptyByteArray; } else { int powerOfTwo = arrayLength <= MinArrayLength ? MinArrayLength : LeastPowerOfTwo (arrayLength); long count = counters.Get(powerOfTwo, true).Increment(); bool aboveThreshold = count > conf.countThreshold; // create a new manager only if the count is above threshold. ByteArrayManager.FixedLengthManager manager = managers.Get(powerOfTwo, aboveThreshold ); if (Log.IsDebugEnabled()) { debugMessage.Get().Append(": count=").Append(count).Append(aboveThreshold ? ", aboveThreshold" : ", belowThreshold"); } array = manager != null?manager.Allocate() : new byte[powerOfTwo]; } if (Log.IsDebugEnabled()) { debugMessage.Get().Append(", return byte[").Append(array.Length).Append("]"); LogDebugMessage(); } return(array); }
public virtual void TestByteArrayManager() { int countThreshold = 32; int countLimit = 64; long countResetTimePeriodMs = 1000L; ByteArrayManager.Impl bam = new ByteArrayManager.Impl(new ByteArrayManager.Conf(countThreshold , countLimit, countResetTimePeriodMs)); ByteArrayManager.CounterMap counters = bam.GetCounters(); ByteArrayManager.ManagerMap managers = bam.GetManagers(); ExecutorService pool = Executors.NewFixedThreadPool(128); TestByteArrayManager.Runner[] runners = new TestByteArrayManager.Runner[TestByteArrayManager.Runner .NumRunners]; Sharpen.Thread[] threads = new Sharpen.Thread[runners.Length]; int num = 1 << 10; for (int i = 0; i < runners.Length; i++) { runners[i] = new TestByteArrayManager.Runner(i, countThreshold, countLimit, pool, i, bam); threads[i] = runners[i].Start(num); } IList <Exception> exceptions = new AList <Exception>(); Sharpen.Thread randomRecycler = new _Thread_332(runners, exceptions, threads); randomRecycler.Start(); randomRecycler.Join(); NUnit.Framework.Assert.IsTrue(exceptions.IsEmpty()); NUnit.Framework.Assert.IsNull(counters.Get(0, false)); for (int i_1 = 1; i_1 < runners.Length; i_1++) { if (!runners[i_1].assertionErrors.IsEmpty()) { foreach (Exception e in runners[i_1].assertionErrors) { Log.Error("AssertionError " + i_1, e); } NUnit.Framework.Assert.Fail(runners[i_1].assertionErrors.Count + " AssertionError(s)" ); } int arrayLength = TestByteArrayManager.Runner.Index2arrayLength(i_1); bool exceedCountThreshold = counters.Get(arrayLength, false).GetCount() > countThreshold; ByteArrayManager.FixedLengthManager m = managers.Get(arrayLength, false); if (exceedCountThreshold) { NUnit.Framework.Assert.IsNotNull(m); } else { NUnit.Framework.Assert.IsNull(m); } } }
/// <returns>the manager for the given array length.</returns> internal virtual ByteArrayManager.FixedLengthManager Get(int arrayLength, bool createIfNotExist ) { lock (this) { ByteArrayManager.FixedLengthManager manager = map[arrayLength]; if (manager == null && createIfNotExist) { manager = new ByteArrayManager.FixedLengthManager(arrayLength, countLimit); map[arrayLength] = manager; } return(manager); } }