public void CreateTrail(Vector3 from, Vector3 to, float distanceBetweenPoints)
 {
     float num = Vector3.Distance(from, to);
     Vector3 normalized = (to - from).normalized;
     float num2 = 0f;
     CircularBuffer<PCTrailPoint> circularBuffer = new CircularBuffer<PCTrailPoint>(this.GetMaxNumberOfPoints());
     int num3 = 0;
     while (num2 < num)
     {
         PCTrailPoint pCTrailPoint = new PCTrailPoint();
         pCTrailPoint.PointNumber = num3;
         pCTrailPoint.Position = from + normalized * num2;
         circularBuffer.Add(pCTrailPoint);
         this.InitialiseNewPoint(pCTrailPoint);
         num3++;
         if (distanceBetweenPoints <= 0f)
         {
             break;
         }
         num2 += distanceBetweenPoints;
     }
     PCTrailPoint pCTrailPoint2 = new PCTrailPoint();
     pCTrailPoint2.PointNumber = num3;
     pCTrailPoint2.Position = to;
     circularBuffer.Add(pCTrailPoint2);
     this.InitialiseNewPoint(pCTrailPoint2);
     PCTrail pCTrail = new PCTrail(this.GetMaxNumberOfPoints());
     pCTrail.Points = circularBuffer;
     this._fadingTrails.Add(pCTrail);
 }
Exemple #2
0
		public void ShouldSaveWithoutOverflow()
		{
			var buffer = new CircularBuffer<int>(5);
			buffer.Add(1);
			buffer.Add(2);
			buffer.Add(3);
			CollectionAssert.AreEqual(new [] { 1, 2, 3 }, buffer);
		}
	/*
	 * coroutine
	IEnumerator YieldSign() {
		print ("spawn yield symbol");
		yield return new WaitForSeconds(2);
		PowerSpawn();
	}

	void  PowerSpawn(){
		print ("spawn power");
	}

	void Start() {
		StartCoroutine(YieldSign());
		print ("disable button");
	}
*/

	void Start(){
		CircularBuffer<int> buffer = new CircularBuffer<int>(2);
		buffer.Add(1);
		buffer.Add(2);
		buffer.Add(3);
		foreach(int i in buffer.Reverse<int>()){
			print (i);
		}
	}
            public void Add_MoreThanCapacity_ProperlyCircles()
            {
                var buffer = new CircularBuffer<int>(3);
                buffer.Add(1);
                buffer.Add(2);
                buffer.Add(3);
                buffer.Add(4);

                Assert.AreEqual(2, buffer.Skip(0).First());
                Assert.AreEqual(3, buffer.Skip(1).First());
                Assert.AreEqual(4, buffer.Skip(2).First());
            }
            public void Remove_ValueType_RemovesItem()
            {
                var buffer = new CircularBuffer<int>(3);

                buffer.Add(1);
                buffer.Add(2);
                buffer.Add(3);

                buffer.Remove(2);

                Assert.AreEqual(2, buffer.Count);
                Assert.IsTrue(buffer.Contains(1));
                Assert.IsFalse(buffer.Contains(2));
                Assert.IsTrue(buffer.Contains(3));
            }
        public void Remove_RemoveSecondItemAndAddTwoItems_OrderIsRight()
        {
            //Create a circular buffer where the first item is overridden
            var target = new CircularBuffer<int>(3) { 1, 2, 3, 4 };

            target.Remove(2);

            target.Add(5);
            target.Add(6);

            var expected = new List<int> { 6, 3, 5 };

            Assert.IsTrue(target.SequenceEqual(expected));
            Assert.IsTrue(target.Capacity == 3);
        }
        public void OrderOfElements(int maxCapacity, int itemsToAdd)
        {
            // Tests that items are indexed in order of newest to oldest,
            // i.e. buffer[0] always returns the last added item.
            var buffer        = new CircularBuffer <int>(maxCapacity);
            var expectedCount = itemsToAdd;

            if (expectedCount > maxCapacity)
            {
                expectedCount = maxCapacity;
            }
            int counter = 0;

            itemsToAdd.Times(() => buffer.Add(counter++));

            // Do not use Assert.Collection, which may make assumptions based on the data type of
            // its argument. Instead, enumerate explicitly.
            int i = itemsToAdd - 1;

            foreach (var bufferValue in buffer)
            {
                Assert.Equal(i, bufferValue);
                i--;
            }
        }
    private void DeriveBlow()
    {
        _dbValues.Add(_dbValue);
        _pitchValues.Add(_pitchValue);

        // Find the average pitch in our records (used to decipher against whistles, clicks, etc).
        float sumPitch = 0;

        foreach (float num in _pitchValues)
        {
            sumPitch += num;
        }

        sumPitch /= _pitchValues.Count;

        // Run low pass filter.
        _lowPassResults = ALPHA * _dbValue + (1.0f - ALPHA) * _lowPassResults;

        // Decides whether this instance of the result could be a blow or not.
        if (_lowPassResults > -30 && sumPitch == 0)
        {
            _blowingTime += 1;
        }
        else
        {
            _blowingTime = 0;
        }
    }
        public void BufferBehavesLikeReadOnlyList(int maxCapacity, int itemsToAdd)
        {
            // Set up buffer.
            var buffer        = new CircularBuffer <int>(maxCapacity);
            var expectedCount = itemsToAdd;

            if (expectedCount > maxCapacity)
            {
                expectedCount = maxCapacity;
            }
            int counter = 0;

            itemsToAdd.Times(() => buffer.Add(counter++));

            // Do not use Assert.Collection, which may make assumptions based on the data type of
            // its argument. Instead, test IReadOnlyList members explicitly.
            Assert.Equal(expectedCount, buffer.Count);

            // Assert that elements are enumerated from 0 to Count - 1.
            int i = 0;

            foreach (var bufferValue in buffer)
            {
                Assert.Equal(buffer[i], bufferValue);
                i++;
            }
            Assert.Equal(expectedCount, i);
        }
Exemple #10
0
        public void CheckNullValueWhenAdding()
        {
            int capacity       = 1;
            var circularBuffer = new CircularBuffer <string>(capacity);

            Assert.Throws <ArgumentNullException>(() => circularBuffer.Add(null));
        }
    private void Add(Candidate candidate)
    {
        //Find a matching buffer for the candidate based on distance. More on this later
        //here maxDistance is the maximum distance a candidate can move each frame
        var matches    = _candidateList.Where(cb => Distance(candidate.Location, cb.Last.Location) < maxDistance);
        int matchCount = matches.Count();

        if (matchCount == 0)
        {
            var cb = new CircularBuffer <Candidate>();
            cb.Add(candidate);
            _candidateList.Add(cb);
        }
        else if (matchCount == 1)
        {
            var match = matches.First();
            if (match.Last.FrameNumber == candidate.FrameNumber)
            {
                // Ambiguous match 1.
                throw new Exception("A candidate was already added to this buffer this frame.");
            }
            match.Add(candidate);
        }
        else
        {
            // Ambiguous match 2.
            throw new Exception("More than one matching buffer was found for this candidate");
        }
    }
Exemple #12
0
 private static void Add(TextReader reader, CircularBuffer <string> buffer, int n)
 {
     for (int i = 0; i < n; i++)
     {
         buffer.Add(reader.ReadLine());
     }
 }
Exemple #13
0
 /// <summary>
 /// Sends a <see cref="WcfLogMessage"/> to the server.
 /// </summary>
 /// <param name="msg">The message that as to be logged.</param>
 public void WriteMessage(WcfLogMessage msg)
 {
     lock (s_MessageBuffer.SyncRoot)
     {
         s_MessageBuffer.Add(msg);
     }
 }
Exemple #14
0
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            CircularBuffer <int> items = new CircularBuffer <int>();

            for (int i = 0; i < 1000; i++)
            {
                items.Add(i);
            }

            Console.WriteLine("CircularBuffer<int> default capacity, current count: " + items.Count);

            ObservableCollection <int> obserableItems = new CircularObservableBuffer <int>(items);

            Console.WriteLine("ObservableCollection<int> default capacity, current count: " + items.Count);

            obserableItems.CollectionChanged += (sender, eventArgs) =>
            {
                Console.WriteLine(eventArgs.Action);
            };

            for (int i = 0; i < 1000; i++)
            {
                obserableItems.Add(i);
            }

            Console.WriteLine("ObservableCollection<int> default capacity, current count: " + obserableItems.Count);


            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
        public void CircularBuffer_IsFullTest()
        {
            var buffer = new CircularBuffer <double>(3);

            buffer.Add(1.2);
            buffer.Add(2.9);
            buffer.Add(10.76);
            Assert.IsTrue(buffer.IsFull);

            var stringBuffer = new CircularBuffer <string>(10);

            stringBuffer.Add("One");
            stringBuffer.Add("Two");
            stringBuffer.Add("Three");
            Assert.IsFalse(stringBuffer.IsFull);
        }
        public void DecreaseMaxCapacity(int itemsToAdd)
        {
            const int initialMaxCapacity   = 7;
            const int decreasedMaxCapacity = 3;

            // Set up buffer.
            var buffer  = new CircularBuffer <int>(initialMaxCapacity);
            int counter = 0;

            itemsToAdd.Times(() => buffer.Add(counter++));

            // Decrease capacity.
            buffer.MaximumCapacity = decreasedMaxCapacity;
            var expectedCount = itemsToAdd;

            if (expectedCount > decreasedMaxCapacity)
            {
                expectedCount = decreasedMaxCapacity;
            }

            // Do not use Assert.Collection, which may make assumptions based on the data type of
            // its argument. Instead, enumerate explicitly.
            Assert.Equal(expectedCount, buffer.Count);

            int i = itemsToAdd - 1;

            foreach (var bufferValue in buffer)
            {
                Assert.Equal(i, bufferValue);
                i--;
            }
        }
Exemple #17
0
        public void TestCircularBufferDeepClones()
        {
            CircularBuffer <int> original = new CircularBuffer <int>(3);

            original.Add(1);
            original.Add(2);

            CircularBuffer <int> clone = original.DeepClone();

            original.Add(3);
            clone.Add(4);

            Assert.AreEqual(original[0], clone[0]);
            Assert.AreEqual(original[1], clone[1]);
            Assert.AreNotEqual(original[2], clone[2]);
        }
        public void TestRollover()
        {
            int bufferSize = 3;
            CircularBuffer<int> circularBuffer = new CircularBuffer<int>(bufferSize);

            for (int i = 0; i < 3; i++)
            {
                circularBuffer.Add(i);
                VerifyContent(circularBuffer, 0, i);
            }

            for (int i = 3; i < 8; i++)
            {
                circularBuffer.Add(i);
                VerifyContent(circularBuffer, i - bufferSize + 1, i);
            }
        }
Exemple #19
0
            public void CopyTo_OverCapacity_RetainsOrder()
            {
                var buffer = new CircularBuffer <int>(3);

                buffer.Add(1);
                buffer.Add(2);
                buffer.Add(3);
                buffer.Add(4);

                var result = new int[3];

                buffer.CopyTo(result, 0);

                Assert.AreEqual(2, result[0]);
                Assert.AreEqual(3, result[1]);
                Assert.AreEqual(4, result[2]);
            }
    void Acceleration()
    {
        AccHistory.Add(Input.acceleration);
        Vector3 lastValue      = AccHistory.Peek();
        Vector3 tiltDifference = Input.acceleration - lastValue;

        _tiltZ = Mathf.Abs(tiltDifference.z);
    }
        public void Should_Put_One_Item()
        {
            var circularBuffer = new CircularBuffer <string>();

            circularBuffer.Add("One");

            Assert.That(circularBuffer.ToList().Count, Is.EqualTo(1));
        }
Exemple #22
0
        public static int?FindBrokenNumber(IEnumerable <int> data)
        {
            const int preambleLength = 25;
            var       numbers        = new CircularBuffer <int>(preambleLength);

            IEnumerator <int> it = data.GetEnumerator();

            while (numbers.Count < preambleLength)
            {
                if (!it.MoveNext())
                {
                    Console.WriteLine("Not enough numbers");
                    return(null);
                }

                numbers.Add(it.Current);
            }

            while (it.MoveNext())
            {
                int  value   = it.Current;
                bool missing = true;
                for (int i = 0; missing && i < preambleLength; i++)
                {
                    int a = numbers[i];
                    int b = value - a;
                    for (int j = i + 1; j < preambleLength; j++)
                    {
                        if (numbers[j] == b)
                        {
                            missing = false;
                            break;
                        }
                    }
                }

                if (missing)
                {
                    return(value);
                }

                numbers.Add(value);
            }

            return(null);
        }
Exemple #23
0
        public void CircularBuffer_Add_AddsItem()
        {
            CircularBuffer <int> q = new CircularBuffer <int>(8);

            q.Add(13);
            Assert.AreEqual(1, q.Count, "CircularBuffer should remember its items");
            Assert.IsTrue(q.SequenceEqual(new[] { 13 }), "CircularBuffer should remember its items");
        }
Exemple #24
0
        public void NextSecond()
        {
            In.Add(InPerSec);
            InPerSec = 0;

            Out.Add(OutPerSec);
            OutPerSec = 0;
        }
        /// <summary>
        /// Insert a trail into this trail renderer.
        /// </summary>
        /// <param name="from">The start position of the trail.</param>
        /// <param name="to">The end position of the trail.</param>
        /// <param name="distanceBetweenPoints">Distance between each point on the trail</param>
        public void CreateTrail(Vector3 from, Vector3 to, float distanceBetweenPoints)
        {
            float distanceBetween = Vector3.Distance(from, to);

            Vector3 dirVector = to - from;

            dirVector = dirVector.normalized;

            float currentLength = 0;

            CircularBuffer <PCTrailPoint> newLine = new CircularBuffer <PCTrailPoint>(GetMaxNumberOfPoints());
            int pointNumber = 0;

            while (currentLength < distanceBetween)
            {
                PCTrailPoint newPoint = new PCTrailPoint();
                newPoint.PointNumber = pointNumber;
                newPoint.Position    = from + dirVector * currentLength;
                newLine.Add(newPoint);
                InitialiseNewPoint(newPoint);

                pointNumber++;

                if (distanceBetweenPoints <= 0)
                {
                    break;
                }
                else
                {
                    currentLength += distanceBetweenPoints;
                }
            }

            PCTrailPoint lastPoint = new PCTrailPoint();

            lastPoint.PointNumber = pointNumber;
            lastPoint.Position    = to;
            newLine.Add(lastPoint);
            InitialiseNewPoint(lastPoint);

            PCTrail newTrail = new PCTrail(GetMaxNumberOfPoints());

            newTrail.Points = newLine;

            _fadingTrails.Add(newTrail);
        }
Exemple #26
0
            public void Enumerate_ForEach_ProperlyEnumerates()
            {
                var buffer = new CircularBuffer <int>(3);

                buffer.Add(1);
                buffer.Add(2);
                buffer.Add(3);
                buffer.Add(4);

                var i = 2;

                foreach (var item in buffer)
                {
                    Assert.AreEqual(i, item);
                    i++;
                }
            }
Exemple #27
0
        internal void Update()
        {
            m_FrameTimesBuffer.Add(DateTime.UtcNow);



            this.FramesPerSecond = m_FrameTimesBuffer.Count * m_TicksSecond / (double)(m_FrameTimesBuffer[m_FrameTimesBuffer.Count - 1].Ticks - m_FrameTimesBuffer[0].Ticks);
        }
        public void SettingAndGettingValues()
        {
            CircularBuffer <int> cb = new CircularBuffer <int>(5);

            Assert.AreEqual(0, cb.Count, "initializes to 0");

            cb.Add(10);
            Assert.AreEqual(1, cb.Count, "added one value. count == 3");

            cb.Add(20);
            cb.Add(30);
            Assert.AreEqual(3, cb.Count, "added three values. count == 3");
            // newest value is at [0], oldest at cb[cb.Count-1]
            Assert.AreEqual(30, cb[0], "circularbuffer[0] == 30");
            Assert.AreEqual(10, cb[cb.Count - 1], "circularbuffer[cb.Count-1] == 10");

            cb.Add(40);
            cb.Add(50);
            Assert.AreEqual(5, cb.Count, "added five values. count == 5");

            cb.Add(60);
            Assert.AreEqual(5, cb.Count, "added six values. count == 5");
            Assert.AreEqual(60, cb[0], "circularbuffer[0] == 60");
            Assert.AreEqual(20, cb[cb.Count - 1], "circularbuffer[cb.Count-1] == 20");

            cb.Add(70);
            cb.Add(80);


            // test getting values via different methods

            int[] expected = new int[] { 80, 70, 60, 50, 40 };

            // test values via indexer
            for (int i = 0; i < cb.Count; i++)
            {
                Assert.AreEqual(expected[i], cb[i], "indexer returned correct value");
            }

            // test values via Enumerator
            int[]             actual     = new int[cb.Count];
            int               idx        = 0;
            IEnumerator <int> enumerator = cb.GetEnumerator();

            while (enumerator.MoveNext())
            {
                actual[idx] = enumerator.Current;
                idx++;
            }
            Assert.AreEqual(expected, actual, "IEnumerator returned correct sequence");

            // test values via Enumerable
            actual = cb.GetEnumerable().ToArray();
            Assert.AreEqual(expected, actual, "IEnumerable returned correct sequence");
        }
    public void TestContainsAfterClear()
    {
        var cb = new CircularBuffer <int>(3);

        cb.Add(1);
        cb.Add(2);
        cb.Add(3);
        cb.Clear();
        Assert.IsFalse(cb.Contains(1));
        Assert.IsFalse(cb.Contains(2));
        Assert.IsFalse(cb.Contains(3));

        cb.Add(1);
        Assert.IsTrue(cb.Contains(1));
        Assert.IsFalse(cb.Contains(2));
        Assert.IsFalse(cb.Contains(3));

        cb.Add(2);
        cb.Add(3);
        Assert.IsTrue(cb.Contains(1));
        Assert.IsTrue(cb.Contains(2));
        Assert.IsTrue(cb.Contains(3));

        cb.Add(4);
        Assert.IsFalse(cb.Contains(1));
        Assert.IsTrue(cb.Contains(2));
        Assert.IsTrue(cb.Contains(3));
        Assert.IsTrue(cb.Contains(4));
    }
Exemple #30
0
            public void Remove_ReferenceType_RemovesItem()
            {
                var buffer = new CircularBuffer <TestRefType>(3);
                var o1     = new TestRefType(Guid.NewGuid());
                var o2     = new TestRefType(Guid.NewGuid());
                var o3     = new TestRefType(Guid.NewGuid());

                buffer.Add(o1);
                buffer.Add(o2);
                buffer.Add(o3);

                buffer.Remove(o2);

                Assert.AreEqual(2, buffer.Count);
                Assert.IsTrue(buffer.Contains(o1));
                Assert.IsFalse(buffer.Contains(o2));
                Assert.IsTrue(buffer.Contains(o3));
            }
Exemple #31
0
		public void ShouldSaveWithOverflow()
		{
			var buffer = new CircularBuffer<int>(4);
			for(var i = 0; i < 6; i++)
			{
				buffer.Add(i);
			}
			Assert.AreEqual(buffer, new [] { 3, 4, 5 });
		}
Exemple #32
0
            public void ContainsRefType_ValueDoesNotExist_ReturnsFalse()
            {
                var buffer = new CircularBuffer <TestRefType>(3);
                var id1    = Guid.NewGuid();
                var id2    = Guid.NewGuid();
                var id3    = Guid.NewGuid();
                var id4    = Guid.NewGuid();

                buffer.Add(new TestRefType(id1));
                buffer.Add(new TestRefType(id2));
                buffer.Add(new TestRefType(id3));
                buffer.Add(new TestRefType(id4));


                var result = buffer.Contains(new TestRefType(id1));

                Assert.IsFalse(result);
            }
Exemple #33
0
            public void ContainsRefType_ValueExists_ReturnsTrue()
            {
                var buffer = new CircularBuffer <TestRefType>(3);
                var id1    = Guid.NewGuid();
                var id2    = Guid.NewGuid();
                var id3    = Guid.NewGuid();
                var id4    = Guid.NewGuid();

                buffer.Add(new TestRefType(id1));
                buffer.Add(new TestRefType(id2));
                buffer.Add(new TestRefType(id3));
                buffer.Add(new TestRefType(id4));


                Assert.IsTrue(buffer.Contains(new TestRefType(id2)));
                Assert.IsTrue(buffer.Contains(new TestRefType(id3)));
                Assert.IsTrue(buffer.Contains(new TestRefType(id4)));
            }
            public void Remove_ReferenceType_RemovesItem()
            {
                var buffer = new CircularBuffer<TestRefType>(3);
                var o1 = new TestRefType(Guid.NewGuid());
                var o2 = new TestRefType(Guid.NewGuid());
                var o3 = new TestRefType(Guid.NewGuid());

                buffer.Add(o1);
                buffer.Add(o2);
                buffer.Add(o3);

                buffer.Remove(o2);

                Assert.AreEqual(2, buffer.Count);
                Assert.IsTrue(buffer.Contains(o1));
                Assert.IsFalse(buffer.Contains(o2));
                Assert.IsTrue(buffer.Contains(o3));
            }
Exemple #35
0
        public void CanToArray()
        {
            var b = new CircularBuffer <int>(3);

            Assert.Empty(b.ToArray());

            b.Add(1);
            Assert.Collection(b.ToArray(), IsInt(1));

            b.Add(2);
            Assert.Collection(b.ToArray(), IsInt(1), IsInt(2));

            b.Add(3);
            Assert.Collection(b.ToArray(), IsInt(1), IsInt(2), IsInt(3));

            b.Add(4);
            Assert.Collection(b.ToArray(), IsInt(2), IsInt(3), IsInt(4));
        }
Exemple #36
0
        public void Teste1()
        {
            CircularBuffer sut = new CircularBuffer(3);

            sut.Add(1);
            var actual = sut.Get().Last();

            Assert.Equal(1, actual);
        }
Exemple #37
0
    private void MeasureDeltaTime()
    {
        float time = Time.realtimeSinceStartup;

        _deltaTime = time - _lastTime;
        _lastTime  = time;
        _deltaTimes.Add(_deltaTime);
        _smoothDeltaTime = Mathf.Lerp(_smoothDeltaTime, _deltaTime, Time.unscaledDeltaTime * 5f);
    }
        internal void AddList(FrameList list)
        {
            if (list == null)
            {
                throw new ArgumentNullException(nameof(list));
            }

            _frameListLists.Add(list);
        }
        public void TestAccessByIndex()
        {
            int bufferSize = 3;
            CircularBuffer<int> circularBuffer = new CircularBuffer<int>(bufferSize);

            for (int i = 0; i < 3; i++)
            {
                circularBuffer.Add(i);
            }
            // not rolled over yet
            Assert.AreEqual(1, circularBuffer[1]);

            for (int i = 3; i < 8; i++)
            {
                circularBuffer.Add(i);
            }
            // rolled over
            Assert.AreEqual(6, circularBuffer[1]);
        }
        public void ShouldSaveWithOverflow()
        {
            var buffer = new CircularBuffer <int>(4);

            for (var i = 0; i < 6; i++)
            {
                buffer.Add(i);
            }
            Assert.AreEqual(buffer, new [] { 3, 4, 5 });
        }
Exemple #41
0
		public void ShouldSaveWithOverflowArray()
		{
			var buffer = new CircularBuffer<int>(4);
			for(var i = 0; i < 6; i++)
			{
				buffer.Add(i);
			}
			var result = new [] { 3, 4, 5 };
			var copy = new int[3];
			buffer.CopyTo(copy, 0);
			Assert.AreEqual(result, copy);
		}
Exemple #42
0
		public void ShouldSaveWithoutOverflowArray()
		{
			var buffer = new CircularBuffer<int>(5);
			var array = new [] { 1, 2, 3, -1, 0 };
			for(var i = 0; i < 3; i++)
			{
				buffer.Add(array[i]);
			}
			var copy = new int[5];
			copy[3] = -1;
			buffer.CopyTo(copy, 0);
			CollectionAssert.AreEqual(array, copy);
		}
            public void ContainsDefaultInt_NotYetFull_ReturnsFalse()
            {
                var buffer = new CircularBuffer<int>(3);
                buffer.Add(1);
                buffer.Add(2);

                var result = buffer.Contains(default(int));

                Assert.IsFalse(result);
            }
            public void ContainsRefType_NullDoesNotExist_ReturnsTrue()
            {
                var buffer = new CircularBuffer<TestRefType>(3);
                var id1 = Guid.NewGuid();
                var id2 = Guid.NewGuid();
                var id3 = Guid.NewGuid();

                buffer.Add(new TestRefType(id1));
                buffer.Add(new TestRefType(id2));
                buffer.Add(new TestRefType(id3));


                Assert.IsFalse(buffer.Contains(null));
            }
Exemple #45
0
        /*
        void OnDrawGizmos()
        {
            if (Application.isPlaying && _controlPoints != null)
            {
                for (int i = 0; i < _controlPoints.Count; i++)
                {
                    Gizmos.color = Color.red;
                    Gizmos.DrawSphere(_controlPoints[i].p, 0.01f);

                    if (i < _controlPoints.Count - 1)
                    {
                        Vector3 Handle1, Handle2;
                        float distanceBetween = Vector3.Distance(_controlPoints[i].p, _controlPoints[i + 1].p) / 2;
                        if (i == 0)
                        {
                            Handle1 = _controlPoints[i].p + (_controlPoints[i + 1].p - _controlPoints[i].p).normalized * distanceBetween;
                        }
                        else
                        {
                            Handle1 = _controlPoints[i].p + (_controlPoints[i + 1].p - _controlPoints[i - 1].p).normalized * distanceBetween;
                        }

                        int nextI = i + 1;

                        if (nextI == _controlPoints.Count - 1)
                        {
                            Handle2 = _controlPoints[nextI].p + (_controlPoints[nextI - 1].p - _controlPoints[nextI].p).normalized * distanceBetween;
                        }
                        else
                        {
                            Handle2 = _controlPoints[nextI].p + (_controlPoints[nextI - 1].p - _controlPoints[nextI + 1].p).normalized * distanceBetween;
                        }

                        Gizmos.color = Color.green;
                        Gizmos.DrawSphere(Handle1, 0.01f);
                        Gizmos.DrawLine(_controlPoints[i].p, Handle1);
                        Gizmos.color = Color.blue;
                        Gizmos.DrawSphere(Handle2, 0.01f);
                        Gizmos.DrawLine(_controlPoints[nextI].p, Handle2);


                        Vector3 current = _controlPoints[i].p;

                        for (int pointBetween = 0; pointBetween < PointsBetweenControlPoints; pointBetween++)
                        {
                            Vector3 next = GetPointAlongCurve(_controlPoints[i].p, Handle1, _controlPoints[i + 1].p, Handle2, ((pointBetween + 1) / ((float)PointsBetweenControlPoints + 1f)), 0.3f);

                            Gizmos.DrawLine(current, next);

                            Gizmos.color = Color.yellow;
                            Gizmos.DrawSphere(next, 0.01f);

                            current = next;
                        }

                        Gizmos.color = Color.blue;
                        Gizmos.DrawLine(current, _controlPoints[i + 1].p);

                    }
                }
            }
        }
        */

        protected override void OnStartEmit()
        {
            _lastPosition = _t.position;
            _distanceMoved = 0;
            _controlPoints = new CircularBuffer<ControlPoint>(MaxControlPoints);

            _controlPoints.Add(new ControlPoint { p = _lastPosition });

            if (TrailData.UseForwardOverride)
            {
                _controlPoints[0].forward = TrailData.ForwardOverrideRelative
                               ? _t.TransformDirection(TrailData.ForwardOverride.normalized)
                               : TrailData.ForwardOverride.normalized;
            }

            AddPoint(new PCTrailPoint(), _lastPosition);

            AddControlPoint(_lastPosition);
        }
Exemple #46
0
        /// <summary>
        /// Insert a trail into this trail renderer. 
        /// </summary>
        /// <param name="from">The start position of the trail.</param>
        /// <param name="to">The end position of the trail.</param>
        /// <param name="distanceBetweenPoints">Distance between each point on the trail</param>
        public void CreateTrail(Vector3 from, Vector3 to, float distanceBetweenPoints)
        {
            float distanceBetween = Vector3.Distance(from, to);

            Vector3 dirVector = to - from;
            dirVector = dirVector.normalized;

            float currentLength = 0;

            CircularBuffer<PCTrailPoint> newLine = new CircularBuffer<PCTrailPoint>(MaxNumberOfPoints);
            int pointNumber = 0;
            while (currentLength < distanceBetween) 
            {
                PCTrailPoint newPoint = new PCTrailPoint();
                newPoint.PointNumber = pointNumber;
                newPoint.Position = from + dirVector*currentLength;
                newLine.Add(newPoint);
                InitialiseNewPoint(newPoint);

                pointNumber++;

                if (distanceBetweenPoints <= 0)
                    break;
                else
                    currentLength += distanceBetweenPoints;
            }

            PCTrailPoint lastPoint = new PCTrailPoint();
            lastPoint.PointNumber = pointNumber;
            lastPoint.Position = to;
            newLine.Add(lastPoint);
            InitialiseNewPoint(lastPoint);

            _fadingTrails.Add(newLine);
        }
            [Ignore] // This test runs for ages, only run if needed
            public void Add_HugeNumber_WorksCorrectly()
            {
                var buffer = new CircularBuffer<long>(100000);
                var random = new Random();

                long lastValue = 0;

                for (long i = 0; i < int.MaxValue + 1000L; i++)
                {
                    lastValue++;
                    buffer.Add(lastValue);
                }

                long testValue = lastValue - buffer.Count + 1;
                foreach (var item in buffer)
                {
                    Assert.AreEqual(testValue, item);
                    testValue++;
                }
            }
            public void ContainsInt_ValueDoesNotExist_ReturnsFalse()
            {
                var buffer = new CircularBuffer<int>(3);
                buffer.Add(1);
                buffer.Add(2);
                buffer.Add(3);
                buffer.Add(4);
                buffer.Add(5);
                buffer.Add(6);
                buffer.Add(7);
                buffer.Add(8);

                var result = buffer.Contains(3);

                Assert.IsFalse(result);
            }
        public void TestSizeIncrease()
        {
            int bufferSize = 3;
            CircularBuffer<int> circularBuffer = new CircularBuffer<int>(bufferSize);

            circularBuffer.AddRange(new int[]{0, 1});

            // Increase when not yet full
            bufferSize = 5;
            circularBuffer.Size = bufferSize;
            VerifyContent(circularBuffer, 0 , 1);

            // fill up
            for (int i = 2; i < 5; i++)
            {
                circularBuffer.Add(i);
                VerifyContent(circularBuffer, 0, i);
            }

            // roll over
            for (int i = 5; i < 8; i++)
            {
                circularBuffer.Add(i);
                VerifyContent(circularBuffer, i - bufferSize + 1, i);
            }

            // Increase when full
            bufferSize = 7;
            circularBuffer.Size = bufferSize;
            VerifyContent(circularBuffer, 3, 7);

            // fill up
            for (int i = 8; i < 10; i++)
            {
                circularBuffer.Add(i);
                VerifyContent(circularBuffer, 3, i);
            }

            // roll over
            for (int i = 10; i < 12; i++)
            {
                circularBuffer.Add(i);
                VerifyContent(circularBuffer, i - bufferSize + 1, i);
            }
        }
            public void Add_WithinCapacity_ProperlyAdds()
            {
                var buffer = new CircularBuffer<int>(3);
                buffer.Add(1);
                buffer.Add(2);

                Assert.AreEqual(1, buffer.Skip(0).First());
                Assert.AreEqual(2, buffer.Skip(1).First());
            }
            public void ContainsInt_ValueExists_ReturnsTrue()
            {
                var buffer = new CircularBuffer<int>(3);
                buffer.Add(1);
                buffer.Add(2);
                buffer.Add(3);
                buffer.Add(4);
                buffer.Add(5);
                buffer.Add(6);
                buffer.Add(7);
                buffer.Add(8);

                Assert.IsTrue(buffer.Contains(6));
                Assert.IsTrue(buffer.Contains(7));
                Assert.IsTrue(buffer.Contains(8));
            }
Exemple #52
0
        internal static IDictionary<int, GCProcess> Collect(
            TraceEventSource source, 
            float sampleIntervalMSec, 
            IDictionary<int, GCProcess> perProc = null, 
            MutableTraceEventStackSource stackSource = null,
            Predicate<TraceEvent> filterFunc = null)
        {
            if (perProc == null)
            {
                perProc = new Dictionary<int, GCProcess>();
            }

            source.Kernel.AddCallbackForEvents(delegate (ProcessCtrTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                var stats = perProc.GetOrCreate(data.ProcessID);
                stats.PeakVirtualMB = ((double)data.PeakVirtualSize) / 1000000.0;
                stats.PeakWorkingSetMB = ((double)data.PeakWorkingSetSize) / 1000000.0;
            });

            Action<RuntimeInformationTraceData> doAtRuntimeStart = delegate (RuntimeInformationTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                var stats = perProc.GetOrCreate(data.ProcessID);
                stats.RuntimeVersion = "V " + data.VMMajorVersion.ToString() + "." + data.VMMinorVersion + "." + data.VMBuildNumber
                    + "." + data.VMQfeNumber;
                stats.StartupFlags = data.StartupFlags;
                stats.Bitness = (data.RuntimeDllPath.ToLower().Contains("framework64") ? 64 : 32);
                if (stats.CommandLine == null)
                    stats.CommandLine = data.CommandLine;
            };

            // log at both startup and rundown
            //var clrRundown = new ClrRundownTraceEventParser(source);
            //clrRundown.RuntimeStart += doAtRuntimeStart;
            source.Clr.AddCallbackForEvent("Runtime/Start", doAtRuntimeStart);

            Action<ProcessTraceData> processStartCallback = data =>
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                var stats = perProc.GetOrCreate(data.ProcessID);

                if (!string.IsNullOrEmpty(data.KernelImageFileName))
                {
                    // When we just have an EventSource (eg, the source was created by 
                    // ETWTraceEventSource), we don't necessarily have the process names
                    // decoded - it all depends on whether we have seen a ProcessStartGroup 
                    // event or not. When the trace was taken after the process started we 
                    // know we didn't see such an event.
                    string name = GetImageName(data.KernelImageFileName);

                    // Strictly speaking, this is not really fixing it 'cause 
                    // it doesn't handle when a process with the same name starts
                    // with the same pid. The chance of that happening is really small.
                    if (stats.isDead == true)
                    {
                        stats = new GCProcess();
                        stats.Init(data);
                        perProc[data.ProcessID] = stats;
                    }
                }

                var commandLine = data.CommandLine;
                if (!string.IsNullOrEmpty(commandLine))
                    stats.CommandLine = commandLine;
            };

            source.Kernel.AddCallbackForEvent("Process/Start", processStartCallback);
            source.Kernel.AddCallbackForEvent("Process/DCStart", processStartCallback);

            Action<ProcessTraceData> processEndCallback = delegate (ProcessTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                var stats = perProc.GetOrCreate(data.ProcessID);

                if (string.IsNullOrEmpty(stats.ProcessName))
                {
                    stats.ProcessName = GetImageName(data.KernelImageFileName);
                }

                if (data.OpcodeName == "Stop")
                {
                    stats.isDead = true;
                }
            };

            source.Kernel.AddCallbackForEvent("Process/Stop", processEndCallback);
            source.Kernel.AddCallbackForEvent("Process/DCStop", processEndCallback);

#if (!CAP)
            CircularBuffer<ThreadWorkSpan> RecentThreadSwitches = new CircularBuffer<ThreadWorkSpan>(10000);
            source.Kernel.AddCallbackForEvent("Thread/CSwitch", delegate (CSwitchTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                RecentThreadSwitches.Add(new ThreadWorkSpan(data));
                GCProcess stats;
                if (perProc.TryGetValue(data.ProcessID, out stats))
                {
                    stats.ThreadId2Priority[data.NewThreadID] = data.NewThreadPriority;
                    if (stats.IsServerGCThread(data.ThreadID) > -1)
                    {
                        stats.ServerGcHeap2ThreadId[data.ProcessorNumber] = data.ThreadID;
                    }
                }

                foreach (var gcProcess in perProc.Values)
                {
                    GCEvent _event = gcProcess.GetCurrentGC();
                    // If we are in the middle of a GC.
                    if (_event != null)
                    {
                        if ((_event.Type != GCType.BackgroundGC) && (gcProcess.isServerGCUsed == 1))
                        {
                            _event.AddServerGcThreadSwitch(new ThreadWorkSpan(data));
                        }
                    }
                }
            });

            CircularBuffer<ThreadWorkSpan> RecentCpuSamples = new CircularBuffer<ThreadWorkSpan>(1000);
            StackSourceSample sample = new StackSourceSample(stackSource);

            source.Kernel.AddCallbackForEvent("PerfInfo/Sample", delegate (SampledProfileTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                RecentCpuSamples.Add(new ThreadWorkSpan(data));
                GCProcess processWithGc = null;
                foreach (var gcProcess in perProc.Values)
                {
                    GCEvent e = gcProcess.GetCurrentGC();
                    // If we are in the middle of a GC.
                    if (e != null)
                    {
                        if ((e.Type != GCType.BackgroundGC) && (gcProcess.isServerGCUsed == 1))
                        {
                            e.AddServerGcSample(new ThreadWorkSpan(data));
                            processWithGc = gcProcess;
                        }
                    }
                }

                if (stackSource != null && processWithGc != null)
                {
                    GCEvent e = processWithGc.GetCurrentGC();
                    sample.Metric = 1;
                    sample.TimeRelativeMSec = data.TimeStampRelativeMSec;
                    var nodeName = string.Format("Server GCs #{0} in {1} (PID:{2})", e.GCNumber, processWithGc.ProcessName, processWithGc.ProcessID);
                    var nodeIndex = stackSource.Interner.FrameIntern(nodeName);
                    sample.StackIndex = stackSource.Interner.CallStackIntern(nodeIndex, stackSource.GetCallStack(data.CallStackIndex(), data));
                    stackSource.AddSample(sample);
                }

                GCProcess stats;
                if (perProc.TryGetValue(data.ProcessID, out stats))
                {
                    if (stats.IsServerGCThread(data.ThreadID) > -1)
                    {
                        stats.ServerGcHeap2ThreadId[data.ProcessorNumber] = data.ThreadID;
                    }

                    var cpuIncrement = sampleIntervalMSec;
                    stats.ProcessCpuMSec += cpuIncrement;

                    GCEvent _event = stats.GetCurrentGC();
                    // If we are in the middle of a GC.
                    if (_event != null)
                    {
                        bool isThreadDoingGC = false;
                        if ((_event.Type != GCType.BackgroundGC) && (stats.isServerGCUsed == 1))
                        {
                            int heapIndex = stats.IsServerGCThread(data.ThreadID);
                            if (heapIndex != -1)
                            {
                                _event.AddServerGCThreadTime(heapIndex, cpuIncrement);
                                isThreadDoingGC = true;
                            }
                        }
                        else if (data.ThreadID == stats.suspendThreadIDGC)
                        {
                            _event.GCCpuMSec += cpuIncrement;
                            isThreadDoingGC = true;
                        }
                        else if (stats.IsBGCThread(data.ThreadID))
                        {
                            Debug.Assert(stats.currentBGC != null);
                            if (stats.currentBGC != null)
                                stats.currentBGC.GCCpuMSec += cpuIncrement;
                            isThreadDoingGC = true;
                        }

                        if (isThreadDoingGC)
                        {
                            stats.GCCpuMSec += cpuIncrement;
                        }
                    }
                }
            });
#endif


            source.Clr.AddCallbackForEvent("GC/SuspendEEStart", delegate (GCSuspendEETraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                var stats = perProc.GetOrCreate(data.ProcessID);
                switch (data.Reason)
                {
                    case GCSuspendEEReason.SuspendForGC:
                        stats.suspendThreadIDGC = data.ThreadID;
                        break;
                    case GCSuspendEEReason.SuspendForGCPrep:
                        stats.suspendThreadIDBGC = data.ThreadID;
                        break;
                    default:
                        stats.suspendThreadIDOther = data.ThreadID;
                        break;
                }

                stats.suspendTimeRelativeMSec = data.TimeStampRelativeMSec;
            });

            // In 2.0 we didn't have this event.

            source.Clr.AddCallbackForEvent("GC/SuspendEEStop", delegate (GCNoUserDataTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);

                if ((stats.suspendThreadIDBGC > 0) && (stats.currentBGC != null))
                {
                    stats.currentBGC._SuspendDurationMSec += data.TimeStampRelativeMSec - stats.suspendTimeRelativeMSec;
                }

                stats.suspendEndTimeRelativeMSec = data.TimeStampRelativeMSec;
            });

            source.Clr.AddCallbackForEvent("GC/RestartEEStop", delegate (GCNoUserDataTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);
                GCEvent _event = stats.GetCurrentGC();
                if (_event != null)
                {
                    if (_event.Type == GCType.BackgroundGC)
                    {
                        stats.AddConcurrentPauseTime(_event, data.TimeStampRelativeMSec);
                    }
                    else
                    {
                        Debug.Assert(_event.PauseStartRelativeMSec != 0);
                        // In 2.0 Concurrent GC, since we don't know the GC's type we can't tell if it's concurrent 
                        // or not. But we know we don't have nested GCs there so simply check if we have received the
                        // GCStop event; if we have it means it's a blocking GC; otherwise it's a concurrent GC so 
                        // simply add the pause time to the GC without making the GC complete.
                        if (_event.GCDurationMSec == 0)
                        {
                            Debug.Assert(_event.is20Event);
                            _event.isConcurrentGC = true;
                            stats.AddConcurrentPauseTime(_event, data.TimeStampRelativeMSec);
                        }
                        else
                        {
                            _event.PauseDurationMSec = data.TimeStampRelativeMSec - _event.PauseStartRelativeMSec;
                            if (_event.HeapStats != null)
                            {
                                _event.isComplete = true;
                                stats.lastCompletedGC = _event;
                            }
                        }
                    }
                }

                // We don't change between a GC end and the pause resume.   
                //Debug.Assert(stats.allocTickAtLastGC == stats.allocTickCurrentMB);
                // Mark that we are not in suspension anymore.  
                stats.suspendTimeRelativeMSec = -1;
                stats.suspendThreadIDOther = -1;
                stats.suspendThreadIDBGC = -1;
                stats.suspendThreadIDGC = -1;
            });

            source.Clr.AddCallbackForEvent("GC/AllocationTick", delegate (GCAllocationTickTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);

                if (stats.HasAllocTickEvents == false)
                {
                    stats.HasAllocTickEvents = true;
                }

                double valueMB = data.GetAllocAmount(ref stats.SeenBadAllocTick) / 1000000.0;

                if (data.AllocationKind == GCAllocationKind.Small)
                {
                    // Would this do the right thing or is it always 0 for SOH since AllocationAmount 
                    // is an int??? 
                    stats.allocTickCurrentMB[0] += valueMB;
                }
                else
                {
                    stats.allocTickCurrentMB[1] += valueMB;
                }
            });

            source.Clr.AddCallbackForEvent("GC/Start", delegate (GCStartTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);

                // We need to filter the scenario where we get 2 GCStart events for each GC.
                if ((stats.suspendThreadIDGC > 0) &&
                    !((stats.events.Count > 0) && stats.events[stats.events.Count - 1].GCNumber == data.Count))
                {
                    GCEvent _event = new GCEvent(stats);
                    Debug.Assert(0 <= data.Depth && data.Depth <= 2);
                    // _event.GCGeneration = data.Depth;   Old style events only have this in the GCStop event.  
                    _event.Reason = data.Reason;
                    _event.GCNumber = data.Count;
                    _event.Type = data.Type;
                    _event.Index = stats.events.Count;
                    _event.is20Event = data.IsClassicProvider;
                    bool isEphemeralGCAtBGCStart = false;
                    // Detecting the ephemeral GC that happens at the beginning of a BGC.
                    if (stats.events.Count > 0)
                    {
                        GCEvent lastGCEvent = stats.events[stats.events.Count - 1];
                        if ((lastGCEvent.Type == GCType.BackgroundGC) &&
                            (!lastGCEvent.isComplete) &&
                            (data.Type == GCType.NonConcurrentGC))
                        {
                            isEphemeralGCAtBGCStart = true;
                        }
                    }

                    Debug.Assert(stats.suspendTimeRelativeMSec != -1);
                    if (isEphemeralGCAtBGCStart)
                    {
                        _event.PauseStartRelativeMSec = data.TimeStampRelativeMSec;
                    }
                    else
                    {
                        _event.PauseStartRelativeMSec = stats.suspendTimeRelativeMSec;
                        if (stats.suspendEndTimeRelativeMSec == -1)
                        {
                            stats.suspendEndTimeRelativeMSec = data.TimeStampRelativeMSec;
                        }

                        _event._SuspendDurationMSec = stats.suspendEndTimeRelativeMSec - stats.suspendTimeRelativeMSec;
                    }

                    _event.GCStartRelativeMSec = data.TimeStampRelativeMSec;
                    stats.events.Add(_event);

                    if (_event.Type == GCType.BackgroundGC)
                    {
                        stats.currentBGC = _event;
                        _event.ProcessCpuAtLastGC = stats.ProcessCpuAtLastGC;
                    }

#if (!CAP)
                    if ((_event.Type != GCType.BackgroundGC) && (stats.isServerGCUsed == 1))
                    {
                        _event.SetUpServerGcHistory();
                        foreach (var s in RecentCpuSamples)
                            _event.AddServerGcSample(s);
                        foreach (var s in RecentThreadSwitches)
                            _event.AddServerGcThreadSwitch(s);
                    }
#endif 
                }
            });

            source.Clr.AddCallbackForEvent("GC/PinObjectAtGCTime", delegate (PinObjectAtGCTimeTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);
                GCEvent _event = stats.GetCurrentGC();
                if (_event != null)
                {
                    if (!_event.PinnedObjects.ContainsKey(data.ObjectID))
                    {
                        _event.PinnedObjects.Add(data.ObjectID, data.ObjectSize);
                    }
                    else
                    {
                        _event.duplicatedPinningReports++;
                    }
                }
            });

            // Some builds have this as a public event, and some have it as a private event.
            // All will move to the private event, so we'll remove this code afterwards.
            source.Clr.AddCallbackForEvent("GC/PinPlugAtGCTime", delegate (PinPlugAtGCTimeTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);
                GCEvent _event = stats.GetCurrentGC();
                if (_event != null)
                {
                    // ObjectID is supposed to be an IntPtr. But "Address" is defined as UInt64 in 
                    // TraceEvent.
                    _event.PinnedPlugs.Add(new GCEvent.PinnedPlug(data.PlugStart, data.PlugEnd));
                }
            });

            source.Clr.AddCallbackForEvent("GC/Mark", delegate (GCMarkWithTypeTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);
                stats.AddServerGCThreadFromMark(data.ThreadID, data.HeapNum);

                GCEvent _event = stats.GetCurrentGC();
                if (_event != null)
                {
                    if (_event.PerHeapMarkTimes == null)
                    {
                        _event.PerHeapMarkTimes = new Dictionary<int, GCEvent.MarkInfo>();
                    }

                    if (!_event.PerHeapMarkTimes.ContainsKey(data.HeapNum))
                    {
                        _event.PerHeapMarkTimes.Add(data.HeapNum, new GCEvent.MarkInfo());
                    }

                    _event.PerHeapMarkTimes[data.HeapNum].MarkTimes[(int)data.Type] = data.TimeStampRelativeMSec;
                    _event.PerHeapMarkTimes[data.HeapNum].MarkPromoted[(int)data.Type] = data.Promoted;
                }
            });

            source.Clr.AddCallbackForEvent("GC/GlobalHeapHistory", delegate (GCGlobalHeapHistoryTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);
                stats.ProcessGlobalHistory(data);
            });

            source.Clr.AddCallbackForEvent("GC/PerHeapHistory", delegate (GCPerHeapHistoryTraceData3 data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);
                stats.ProcessPerHeapHistory(data);
            });

#if HAS_PRIVATE_GC_EVENTS
            // See if the source knows about the CLR Private provider, if it does, then 
            var gcPrivate = new ClrPrivateTraceEventParser(source);

            gcPrivate.GCPinPlugAtGCTime += delegate (PinPlugAtGCTimeTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc[data];
                GCEvent _event = stats.GetCurrentGC();
                if (_event != null)
                {
                    // ObjectID is supposed to be an IntPtr. But "Address" is defined as UInt64 in 
                    // TraceEvent.
                    _event.PinnedPlugs.Add(new GCEvent.PinnedPlug(data.PlugStart, data.PlugEnd));
                }
            };

            // Sometimes at the end of a trace I see only some mark events are included in the trace and they
            // are not in order, so need to anticipate that scenario.
            gcPrivate.GCMarkStackRoots += delegate (GCMarkTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc[data];
                stats.AddServerGCThreadFromMark(data.ThreadID, data.HeapNum);

                GCEvent _event = stats.GetCurrentGC();
                if (_event != null)
                {
                    if (_event.PerHeapMarkTimes == null)
                    {
                        _event.PerHeapMarkTimes = new Dictionary<int, GCEvent.MarkInfo>();
                    }

                    if (!_event.PerHeapMarkTimes.ContainsKey(data.HeapNum))
                    {
                        _event.PerHeapMarkTimes.Add(data.HeapNum, new GCEvent.MarkInfo(false));
                    }

                    _event.PerHeapMarkTimes[data.HeapNum].MarkTimes[(int)MarkRootType.MarkStack] = data.TimeStampRelativeMSec;
                }
            };

            gcPrivate.GCMarkFinalizeQueueRoots += delegate (GCMarkTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc[data];
                GCEvent _event = stats.GetCurrentGC();
                if (_event != null)
                {
                    if ((_event.PerHeapMarkTimes != null) && _event.PerHeapMarkTimes.ContainsKey(data.HeapNum))
                    {
                        _event.PerHeapMarkTimes[data.HeapNum].MarkTimes[(int)MarkRootType.MarkFQ] =
                            data.TimeStampRelativeMSec;
                    }
                }
            };

            gcPrivate.GCMarkHandles += delegate (GCMarkTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc[data];
                GCEvent _event = stats.GetCurrentGC();
                if (_event != null)
                {
                    if ((_event.PerHeapMarkTimes != null) && _event.PerHeapMarkTimes.ContainsKey(data.HeapNum))
                    {
                        _event.PerHeapMarkTimes[data.HeapNum].MarkTimes[(int)MarkRootType.MarkHandles] =
                           data.TimeStampRelativeMSec;
                    }
                }
            };

            gcPrivate.GCMarkCards += delegate (GCMarkTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc[data];
                GCEvent _event = stats.GetCurrentGC();
                if (_event != null)
                {
                    if ((_event.PerHeapMarkTimes != null) && _event.PerHeapMarkTimes.ContainsKey(data.HeapNum))
                    {
                        _event.PerHeapMarkTimes[data.HeapNum].MarkTimes[(int)MarkRootType.MarkOlder] =
                            data.TimeStampRelativeMSec;
                    }
                }
            };

            gcPrivate.GCGlobalHeapHistory += delegate (GCGlobalHeapHistoryTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc[data];
                stats.ProcessGlobalHistory(data);
            };

            gcPrivate.GCPerHeapHistory += delegate (GCPerHeapHistoryTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc[data];
                stats.ProcessPerHeapHistory(data);
            };

            gcPrivate.GCBGCStart += delegate (GCNoUserDataTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc[data];
                if (stats.currentBGC != null)
                {
                    if (stats.backgroundGCThreads == null)
                    {
                        stats.backgroundGCThreads = new Dictionary<int, object>(16);
                    }
                    stats.backgroundGCThreads[data.ThreadID] = null;
                }
            };
#endif

            source.Clr.AddCallbackForEvent("GC/Stop", delegate (GCEndTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);
                GCEvent _event = stats.GetCurrentGC();
                if (_event != null)
                {
                    _event.GCDurationMSec = data.TimeStampRelativeMSec - _event.GCStartRelativeMSec;
                    _event.GCGeneration = data.Depth;
                    _event.GCEnd();
                }
            });

            source.Clr.AddCallbackForEvent("GC/HeapStats", delegate (GCHeapStatsTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);
                GCEvent _event = stats.GetCurrentGC();

                var sizeAfterMB = (data.GenerationSize1 + data.GenerationSize2 + data.GenerationSize3) / 1000000.0;
                if (_event != null)
                {
                    _event.HeapStats = (GCHeapStatsTraceData)data.Clone();

                    if (_event.Type == GCType.BackgroundGC)
                    {
                        _event.ProcessCpuMSec = stats.ProcessCpuMSec - _event.ProcessCpuAtLastGC;
                        _event.DurationSinceLastRestartMSec = data.TimeStampRelativeMSec - stats.lastRestartEndTimeRelativeMSec;
                    }
                    else
                    {
                        _event.ProcessCpuMSec = stats.ProcessCpuMSec - stats.ProcessCpuAtLastGC;
                        _event.DurationSinceLastRestartMSec = _event.PauseStartRelativeMSec - stats.lastRestartEndTimeRelativeMSec;
                    }

                    if (stats.HasAllocTickEvents)
                    {
                        _event.HasAllocTickEvents = true;
                        _event.AllocedSinceLastGCBasedOnAllocTickMB[0] = stats.allocTickCurrentMB[0] - stats.allocTickAtLastGC[0];
                        _event.AllocedSinceLastGCBasedOnAllocTickMB[1] = stats.allocTickCurrentMB[1] - stats.allocTickAtLastGC[1];
                    }

                    // This is where a background GC ends.
                    if ((_event.Type == GCType.BackgroundGC) && (stats.currentBGC != null))
                    {
                        stats.currentBGC.isComplete = true;
                        stats.lastCompletedGC = stats.currentBGC;
                        stats.currentBGC = null;
                    }

                    if (_event.isConcurrentGC)
                    {
                        Debug.Assert(_event.is20Event);
                        _event.isComplete = true;
                        stats.lastCompletedGC = _event;
                    }
                }

                stats.ProcessCpuAtLastGC = stats.ProcessCpuMSec;
                stats.allocTickAtLastGC[0] = stats.allocTickCurrentMB[0];
                stats.allocTickAtLastGC[1] = stats.allocTickCurrentMB[1];
                stats.lastRestartEndTimeRelativeMSec = data.TimeStampRelativeMSec;
            });

            source.Clr.AddCallbackForEvent("GC/TerminateConcurrentThread", delegate (GCTerminateConcurrentThreadTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc.GetOrCreate(data.ProcessID);
                if (stats.backgroundGCThreads != null)
                {
                    stats.backgroundGCThreads = null;
                }
            });

#if HAS_PRIVATE_GC_EVENTS
            gcPrivate.GCBGCAllocWaitStart += delegate (BGCAllocWaitTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc[data];
                Debug.Assert(stats.currentBGC != null);

                if (stats.currentBGC != null)
                {
                    stats.currentBGC.AddLOHWaitThreadInfo(data.ThreadID, data.TimeStampRelativeMSec, data.Reason, true);
                }
            };

            gcPrivate.GCBGCAllocWaitStop += delegate (BGCAllocWaitTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess stats = perProc[data];

                GCEvent _event = stats.GetLastBGC();

                if (_event != null)
                {
                    _event.AddLOHWaitThreadInfo(data.ThreadID, data.TimeStampRelativeMSec, data.Reason, false);
                }
            };

            gcPrivate.GCJoin += delegate (GCJoinTraceData data)
            {
                if (filterFunc != null && !filterFunc.Invoke(data))
                {
                    return;
                }

                GCProcess gcProcess = perProc[data];
                GCEvent _event = gcProcess.GetCurrentGC();
                if (_event != null)
                {
                    _event.AddGcJoin(data);
                }
            };

            source.Process();
#endif
            return perProc;
        }
            public void Enumerate_Modify_ThrowsException()
            {
                var buffer = new CircularBuffer<int>(3);
                buffer.Add(1);
                buffer.Add(2);
                buffer.Add(3);
                buffer.Add(4);

                bool thrown = false;

                try
                {
                    foreach (var item in buffer)
                    {
                        buffer.Add(5);
                    }
                }
                catch (InvalidOperationException)
                {
                    if (thrown) Assert.Fail("Thrown was set more than once");
                    thrown = true;
                }

                Assert.IsTrue(thrown);
            }
            public void CopyToWithIndex_OverCapacity_RetainsOrder()
            {
                var buffer = new CircularBuffer<int>(3);
                buffer.Add(1);
                buffer.Add(2);
                buffer.Add(3);
                buffer.Add(4);

                var result = new int[5];

                buffer.CopyTo(result, 2);

                Assert.AreEqual(0, result[0]);
                Assert.AreEqual(0, result[1]);
                Assert.AreEqual(2, result[2]);
                Assert.AreEqual(3, result[3]);
                Assert.AreEqual(4, result[4]);
            }
            public void ContainsRefType_ValueExists_ReturnsTrue()
            {
                var buffer = new CircularBuffer<TestRefType>(3);
                var id1 = Guid.NewGuid();
                var id2 = Guid.NewGuid();
                var id3 = Guid.NewGuid();
                var id4 = Guid.NewGuid();

                buffer.Add(new TestRefType(id1));
                buffer.Add(new TestRefType(id2));
                buffer.Add(new TestRefType(id3));
                buffer.Add(new TestRefType(id4));


                Assert.IsTrue(buffer.Contains(new TestRefType(id2)));
                Assert.IsTrue(buffer.Contains(new TestRefType(id3)));
                Assert.IsTrue(buffer.Contains(new TestRefType(id4)));
            }
            public void ContainsRefType_ValueDoesNotExist_ReturnsFalse()
            {
                var buffer = new CircularBuffer<TestRefType>(3);
                var id1 = Guid.NewGuid();
                var id2 = Guid.NewGuid();
                var id3 = Guid.NewGuid();
                var id4 = Guid.NewGuid();

                buffer.Add(new TestRefType(id1));
                buffer.Add(new TestRefType(id2));
                buffer.Add(new TestRefType(id3));
                buffer.Add(new TestRefType(id4));


                var result = buffer.Contains(new TestRefType(id1));

                Assert.IsFalse(result);
            }
            public void CopyTo_WithinCapacity_OnlyCopiesAddedItems()
            {
                var buffer = new CircularBuffer<int>(3);
                buffer.Add(1);
                buffer.Add(2);

                var result = new int[2];

                buffer.CopyTo(result, 0);

                Assert.AreEqual(1, result[0]);
                Assert.AreEqual(2, result[1]);
            }
            public void Enumerate_ForEach_ProperlyEnumerates()
            {
                var buffer = new CircularBuffer<int>(3);
                buffer.Add(1);
                buffer.Add(2);
                buffer.Add(3);
                buffer.Add(4);

                var i = 2;
                foreach (var item in buffer)
                {
                    Assert.AreEqual(i, item);
                    i++;
                }
            }
            public void ContainsDefaultRefType_NotYetFull_ReturnsFalse()
            {
                var buffer = new CircularBuffer<TestRefType>(3);
                buffer.Add(new TestRefType(Guid.NewGuid()));
                buffer.Add(new TestRefType(Guid.NewGuid()));

                var result = buffer.Contains(default(TestRefType));

                Assert.IsFalse(result);
            }
            public void Enumerate_Reset_ProperlyResets()
            {
                var buffer = new CircularBuffer<int>(3);
                buffer.Add(1);
                buffer.Add(2);
                buffer.Add(3);

                var en = buffer.GetEnumerator();
                en.MoveNext();
                Assert.AreEqual(1, en.Current);
                en.MoveNext();
                Assert.AreEqual(2, en.Current);
                en.Reset();
                en.MoveNext();
                Assert.AreEqual(1, en.Current);
                en.MoveNext();
                Assert.AreEqual(2, en.Current);
            }