<commit_before>// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace System.Collections.Immutable.Test
{
    public class ImmutableInterlockedTests
    {
        [Fact]
        public void ApplyChange_StartWithNull()
        {
            ImmutableList<int> list = null;
            Assert.True(ImmutableInterlocked.ApplyChange(ref list, l => { Assert.Null(l); return ImmutableList.Create(1); }));
            Assert.Equal(1, list.Count);
            Assert.Equal(1, list[0]);
        }

        [Fact]
        public void ApplyChange_IncrementalUpdate()
        {
            ImmutableList<int> list = ImmutableList.Create(1);
            Assert.True(ImmutableInterlocked.ApplyChange(ref list, l => l.Add(2)));
            Assert.Equal(2, list.Count);
            Assert.Equal(1, list[0]);
            Assert.Equal(2, list[1]);
        }

        [Fact]
        public void ApplyChange_FuncThrowsThrough()
        {
            ImmutableList<int> list = ImmutableList.Create(1);
            Assert.Throws<InvalidOperationException>(() => ImmutableInterlocked.ApplyChange(ref list, l => { throw new InvalidOperationException(); }));
        }

        [Fact]
        public void ApplyChange_NoEffectualChange()
        {
            ImmutableList<int> list = ImmutableList.Create<int>(1);
            Assert.False(ImmutableInterlocked.ApplyChange(ref list, l => l));
        }

        [Fact]
        public void ApplyChange_HighConcurrency()
        {
            ImmutableList<int> list = ImmutableList.Create<int>();
            int concurrencyLevel = Environment.ProcessorCount;
            int iterations = 500;
            Task[] tasks = new Task[concurrencyLevel];
            var countdown = new CountdownEvent(tasks.Length);
            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i] = Task.Run(delegate
                {
                    // Maximize concurrency by blocking this thread until all the other threads are ready to go as well.
                    countdown.Signal();
                    countdown.Wait();

                    for (int j = 0; j < iterations; j++)
                    {
                        Assert.True(ImmutableInterlocked.ApplyChange(ref list, l => l.Add(l.Count)));
                    }
                });
            }

            Task.WaitAll(tasks);
            Assert.Equal(concurrencyLevel * iterations, list.Count);
            for (int i = 0; i < list.Count; i++)
            {
                Assert.Equal(i, list[i]);
            }
        }<commit_msg>Switch from using CountdownEvent to Barrier in test.<commit_after>// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace System.Collections.Immutable.Test
{
    public class ImmutableInterlockedTests
    {
        [Fact]
        public void ApplyChange_StartWithNull()
        {
            ImmutableList<int> list = null;
            Assert.True(ImmutableInterlocked.ApplyChange(ref list, l => { Assert.Null(l); return ImmutableList.Create(1); }));
            Assert.Equal(1, list.Count);
            Assert.Equal(1, list[0]);
        }

        [Fact]
        public void ApplyChange_IncrementalUpdate()
        {
            ImmutableList<int> list = ImmutableList.Create(1);
            Assert.True(ImmutableInterlocked.ApplyChange(ref list, l => l.Add(2)));
            Assert.Equal(2, list.Count);
            Assert.Equal(1, list[0]);
            Assert.Equal(2, list[1]);
        }

        [Fact]
        public void ApplyChange_FuncThrowsThrough()
        {
            ImmutableList<int> list = ImmutableList.Create(1);
            Assert.Throws<InvalidOperationException>(() => ImmutableInterlocked.ApplyChange(ref list, l => { throw new InvalidOperationException(); }));
        }

        [Fact]
        public void ApplyChange_NoEffectualChange()
        {
            ImmutableList<int> list = ImmutableList.Create<int>(1);
            Assert.False(ImmutableInterlocked.ApplyChange(ref list, l => l));
        }

        [Fact]
        public void ApplyChange_HighConcurrency()
        {
            ImmutableList<int> list = ImmutableList.Create<int>();
            int concurrencyLevel = Environment.ProcessorCount;
            int iterations = 500;
            Task[] tasks = new Task[concurrencyLevel];
            var barrier = new Barrier(tasks.Length);
            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i] = Task.Run(delegate
                {
                    // Maximize concurrency by blocking this thread until all the other threads are ready to go as well.
                    barrier.SignalAndWait();

                    for (int j = 0; j < iterations; j++)
                    {
                        Assert.True(ImmutableInterlocked.ApplyChange(ref list, l => l.Add(l.Count)));
                    }
                });
            }

            Task.WaitAll(tasks);
            Assert.Equal(concurrencyLevel * iterations, list.Count);
            for (int i = 0; i < list.Count; i++)
            {
                Assert.Equal(i, list[i]);
            }
        }
{'fraction_non_alphanumeric': 0.1050996161579236, 'fraction_numerical': 0.006945713763480168, 'mean_word_length': 1.8485163977095262, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7660708', 'n_tokens_mistral': 1454, 'n_tokens_neox': 1406, 'n_words': 342}