protected override void setCountAtIndex(int index, long value) { try { wrp.ReaderLock(); Debug.Assert(countsArrayLength == activeCounts.Length); Debug.Assert(countsArrayLength == inactiveCounts.Length); activeCounts.SetValue(NormalizeIndex(index, activeCountsNormalizingIndexOffset, activeCounts.Length), value); inactiveCounts.SetValue(NormalizeIndex(index, inactiveCountsNormalizingIndexOffset, inactiveCounts.Length), 0); } finally { wrp.ReaderUnlock(); } }
protected internal override void clearCounts() { try { _wrp.ReaderLock(); Debug.Assert(countsArrayLength == _activeCounts.Length); Debug.Assert(countsArrayLength == _inactiveCounts.Length); for (var i = 0; i < _activeCounts.Length; i++) { _activeCounts.SetValue(i, 0); _inactiveCounts.SetValue(i, 0); } TotalCount.Reset(); } finally { _wrp.ReaderUnlock(); } }
public void can_compare_and_set() { var array = new AtomicLongArray(10); array.SetValue(1, 10); array.CompareAndSwap(1, 5, 11).Should().Be(false); array.GetValue(1).Should().Be(10); array.CompareAndSwap(1, 10, 11).Should().Be(true); array.GetValue(1).Should().Be(11); }
public void can_increment() { var array = new AtomicLongArray(10); array.SetValue(1, 3); array.Increment(1).Should().Be(4); array.Increment(1, 4).Should().Be(8); array.GetAndIncrement(1).Should().Be(8); array.GetValue(1).Should().Be(9); }
public void can_decrement() { var array = new AtomicLongArray(10); array.SetValue(1, 10); array.Decrement(1).Should().Be(9); array.Decrement(1, 4).Should().Be(5); array.GetAndDecrement(1).Should().Be(5); array.GetValue(1).Should().Be(4); }
public void AtomicLongArray_CanCompareAndSet() { var array = new AtomicLongArray(10); array.SetValue(1, 10); array.CompareAndSwap(1, 5, 11).Should().Be(false); array.GetValue(1).Should().Be(10); array.CompareAndSwap(1, 10, 11).Should().Be(true); array.GetValue(1).Should().Be(11); }
public void AtomicLongArray_CanDecrement() { var array = new AtomicLongArray(10); array.SetValue(1, 10); array.Decrement(1).Should().Be(9); array.Decrement(1, 4).Should().Be(5); array.GetAndDecrement(1).Should().Be(5); array.GetValue(1).Should().Be(4); }
public void AtomicLongArray_CanIncrement() { var array = new AtomicLongArray(10); array.SetValue(1, 3); array.Increment(1).Should().Be(4); array.Increment(1, 4).Should().Be(8); array.GetAndIncrement(1).Should().Be(8); array.GetValue(1).Should().Be(9); }
public void can_get_and_set_value() { var array = new AtomicLongArray(10); array.SetValue(1, 3); array.GetValue(1).Should().Be(3); array.GetAndSet(1, 4).Should().Be(3); array.GetValue(1).Should().Be(4); array.GetAndReset(1).Should().Be(4); array.GetValue(1).Should().Be(0); }
public void AtomicLongArray_CanGetAndSetValue() { var array = new AtomicLongArray(10); array.SetValue(1, 3); array.GetValue(1).Should().Be(3); array.GetAndSet(1, 4).Should().Be(3); array.GetValue(1).Should().Be(4); array.GetAndReset(1).Should().Be(4); array.GetValue(1).Should().Be(0); }
internal protected override void resize(long newHighestTrackableValue) { try { wrp.ReaderLock(); Debug.Assert(countsArrayLength == activeCounts.Length); Debug.Assert(countsArrayLength == inactiveCounts.Length); int newArrayLength = determineArrayLengthNeeded(newHighestTrackableValue); int countsDelta = newArrayLength - countsArrayLength; if (countsDelta <= 0) { // This resize need was already covered by a concurrent resize op. return; } int oldNormalizedZeroIndex = NormalizeIndex(0, inactiveCountsNormalizingIndexOffset, inactiveCounts.Length); // Resize the current inactiveCounts: AtomicLongArray oldInactiveCounts = inactiveCounts; inactiveCounts = new AtomicLongArray(newArrayLength); // Copy inactive contents to newly sized inactiveCounts: for (int i = 0; i < oldInactiveCounts.Length; i++) { inactiveCounts.SetValue(i, oldInactiveCounts.GetValue(i)); } if (oldNormalizedZeroIndex != 0) { // We need to shift the stuff from the zero index and up to the end of the array: int newNormalizedZeroIndex = oldNormalizedZeroIndex + countsDelta; int lengthToCopy = (newArrayLength - countsDelta) - oldNormalizedZeroIndex; int src, dst; for (src = oldNormalizedZeroIndex, dst = newNormalizedZeroIndex; src < oldNormalizedZeroIndex + lengthToCopy; src++, dst++) { inactiveCounts.SetValue(dst, oldInactiveCounts.GetValue(src)); } } // switch active and inactive: var tmp = activeCounts; var tmpOffset = activeCountsNormalizingIndexOffset; activeCounts = inactiveCounts; activeCountsNormalizingIndexOffset = inactiveCountsNormalizingIndexOffset; inactiveCounts = tmp; inactiveCountsNormalizingIndexOffset = tmpOffset; wrp.FlipPhase(); // Resize the newly inactiveCounts: oldInactiveCounts = inactiveCounts; inactiveCounts = new AtomicLongArray(newArrayLength); // Copy inactive contents to newly sized inactiveCounts: for (int i = 0; i < oldInactiveCounts.Length; i++) { inactiveCounts.SetValue(i, oldInactiveCounts.GetValue(i)); } if (oldNormalizedZeroIndex != 0) { // We need to shift the stuff from the zero index and up to the end of the array: int newNormalizedZeroIndex = oldNormalizedZeroIndex + countsDelta; int lengthToCopy = (newArrayLength - countsDelta) - oldNormalizedZeroIndex; int src, dst; for (src = oldNormalizedZeroIndex, dst = newNormalizedZeroIndex; src < oldNormalizedZeroIndex + lengthToCopy; src++, dst++) { inactiveCounts.SetValue(dst, oldInactiveCounts.GetValue(src)); } } // switch active and inactive again: tmp = activeCounts; activeCounts = inactiveCounts; inactiveCounts = tmp; wrp.FlipPhase(); // At this point, both active and inactive have been safely resized, // and the switch in each was done without any writers modifying it in flight. // We resized things. We can now make the historam establish size accordingly for future recordings: establishSize(newHighestTrackableValue); Debug.Assert(countsArrayLength == activeCounts.Length); Debug.Assert(countsArrayLength == inactiveCounts.Length); } finally { wrp.ReaderUnlock(); } }
private void setNormalizingIndexOffset( int normalizingIndexOffset, int shiftedAmount, bool lowestHalfBucketPopulated) { try { wrp.ReaderLock(); Debug.Assert(countsArrayLength == activeCounts.Length); Debug.Assert(countsArrayLength == inactiveCounts.Length); if (normalizingIndexOffset == activeCountsNormalizingIndexOffset) { return; // Nothing to do. } // Save and clear the inactive 0 value count: int zeroIndex = NormalizeIndex(0, inactiveCountsNormalizingIndexOffset, inactiveCounts.Length); long inactiveZeroValueCount = inactiveCounts.GetValue(zeroIndex); inactiveCounts.SetValue(zeroIndex, 0); // Change the normalizingIndexOffset on the current inactiveCounts: inactiveCountsNormalizingIndexOffset = normalizingIndexOffset; //inactiveCounts.setNormalizingIndexOffset(normalizingIndexOffset); // Handle the inactive lowest half bucket: if ((shiftedAmount > 0) && lowestHalfBucketPopulated) { shiftLowestInactiveHalfBucketContentsLeft(shiftedAmount); } // Restore the inactive 0 value count: zeroIndex = NormalizeIndex(0, inactiveCountsNormalizingIndexOffset, inactiveCounts.Length); inactiveCounts.SetValue(zeroIndex, inactiveZeroValueCount); // switch active and inactive: var tmp = activeCounts; var tmpOffset = activeCountsNormalizingIndexOffset; activeCounts = inactiveCounts; activeCountsNormalizingIndexOffset = inactiveCountsNormalizingIndexOffset; inactiveCounts = tmp; inactiveCountsNormalizingIndexOffset = tmpOffset; wrp.FlipPhase(); // Save and clear the newly inactive 0 value count: zeroIndex = NormalizeIndex(0, inactiveCountsNormalizingIndexOffset, inactiveCounts.Length); inactiveZeroValueCount = inactiveCounts.GetValue(zeroIndex); inactiveCounts.SetValue(zeroIndex, 0); // Change the normalizingIndexOffset on the newly inactiveCounts: inactiveCountsNormalizingIndexOffset = normalizingIndexOffset; //inactiveCounts.setNormalizingIndexOffset(normalizingIndexOffset); // Handle the newly inactive lowest half bucket: if ((shiftedAmount > 0) && lowestHalfBucketPopulated) { shiftLowestInactiveHalfBucketContentsLeft(shiftedAmount); } // Restore the newly inactive 0 value count: zeroIndex = NormalizeIndex(0, inactiveCountsNormalizingIndexOffset, inactiveCounts.Length); inactiveCounts.SetValue(zeroIndex, inactiveZeroValueCount); // switch active and inactive again: tmp = activeCounts; tmpOffset = activeCountsNormalizingIndexOffset; activeCounts = inactiveCounts; activeCountsNormalizingIndexOffset = inactiveCountsNormalizingIndexOffset; inactiveCounts = tmp; inactiveCountsNormalizingIndexOffset = tmpOffset; wrp.FlipPhase(); // At this point, both active and inactive have normalizingIndexOffset safely set, // and the switch in each was done without any writers using the wrong value in flight. } finally { wrp.ReaderUnlock(); } }