public void ConcurrentAddTest()
        {
            var processorCount = Environment.ProcessorCount;
            var entryCount     = processorCount * 100000;
            var allNumbers     = Enumerable.Range(1, entryCount).ToArray();
            var groupsPerTask  = allNumbers.GroupBy(number => number % processorCount)
                                 .ToArray();
            var concurrentArray = new ConcurrentArrayBuilder <int, object>().WithCapacity(LinearDoublingPrimeStrategy.GetNextCapacity(entryCount))
                                  .Build();

            Parallel.ForEach(groupsPerTask, group =>
            {
                foreach (var number in group)
                {
                    var addResult = concurrentArray.TryAdd(new Entry <int, object>(number.GetHashCode(), number, null));
                    addResult.OperationResult.Should().Be(AddResult.AddSuccessful);
                }
            });

            concurrentArray.Count.Should().Be(allNumbers.Length);
            foreach (var number in allNumbers)
            {
                var entry = concurrentArray.Find(number.GetHashCode(), number);
                entry.Should().NotBeNull();
            }
        }
        public void InitialCapacity(int initialCapacity)
        {
            var concurrentArray = new ConcurrentArrayBuilder <string, object>().WithCapacity(initialCapacity)
                                  .Build();

            concurrentArray.Capacity.Should().Be(initialCapacity);
        }
        public void FindWhenEmpty()
        {
            var concurrentArray = new ConcurrentArrayBuilder <int, object>().Build();

            var foundEntry = concurrentArray.Find(42, 42);

            foundEntry.Should().BeNull();
        }
        public void ReadProcessVolatile()
        {
            var concurrentArray = new ConcurrentArrayBuilder <int, Type>().Build();

            var process = concurrentArray.ReadGrowArrayProcessVolatile();

            process.Should().BeNull();
        }
        public void FindKeyNull()
        {
            var concurrentArray = new ConcurrentArrayBuilder <string, object>().Build();

            Action act = () => concurrentArray.Find(42, null);

            act.ShouldThrow <ArgumentNullException>()
            .And.ParamName.Should().Be("key");
        }
        public void TryAddParameterNull()
        {
            var concurrentArray = new ConcurrentArrayBuilder <string, object>().Build();

            Action act = () => concurrentArray.TryAdd(null);

            act.ShouldThrow <ArgumentNullException>()
            .And.ParamName.Should().Be("entry");
        }
        public void SimpleAddAndRetrieve(Entry <string, string> entry)
        {
            var concurrentArray = new ConcurrentArrayBuilder <string, string>().Build();

            var tryAddResult = concurrentArray.TryAdd(entry);
            var foundEntry   = concurrentArray.Find(entry.HashCode, entry.Key);

            tryAddResult.OperationResult.Should().Be(AddResult.AddSuccessful);
            foundEntry.Should().BeSameAs(entry);
        }
        public void TryAddWhenArrayIsFull()
        {
            var concurrentArray = new ConcurrentArrayBuilder <int, object>().WithCapacity(4)
                                  .Build()
                                  .FillArray();

            var addInfo = concurrentArray.TryAdd(new Entry <int, object>(5, 5, null));

            addInfo.OperationResult.Should().Be(AddResult.ArrayFull);
            addInfo.TargetEntry.Should().BeNull();
        }
        public void CountMustReflectAddedEntries(Entry <int, string>[] entries)
        {
            var concurrentArray = new ConcurrentArrayBuilder <int, string>().Build();

            foreach (var entry in entries)
            {
                concurrentArray.TryAdd(entry);
            }

            concurrentArray.Count.Should().Be(entries.Length);
        }
        public void TryAddEntryExists()
        {
            var concurrentArray = new ConcurrentArrayBuilder <string, object>().Build();
            var existingEntry   = new Entry <string, object>(42, "Foo", null);

            concurrentArray.TryAdd(existingEntry);

            var addInfo = concurrentArray.TryAdd(new Entry <string, object>(42, "Foo", "Bar"));

            addInfo.OperationResult.Should().Be(AddResult.ExistingEntryFound);
            addInfo.TargetEntry.Should().Be(existingEntry);
        }
        public void CustomKeyComparer()
        {
            var keyComparerMock = new KeyComparerMock();
            var concurrentArray = new ConcurrentArrayBuilder <int, object>().WithKeyComparer(keyComparerMock)
                                  .Build();

            concurrentArray.TryAdd(new Entry <int, object>(6, 6, null));

            concurrentArray.Find(6, 6);

            keyComparerMock.EqualsMustHaveBeenCalledAtLeastOnce();
        }
        public void CreateGrowArrayProcess()
        {
            var concurrentArray  = new ConcurrentArrayBuilder <string, object>().Build();
            var newArraySize     = LinearDoublingPrimeStrategy.GetNextCapacity(concurrentArray.Capacity);
            var spy              = new ExchangeArraySpy <string, object>();
            var growArrayProcess = new GrowArrayProcess <string, object>(concurrentArray, newArraySize, spy.ExchangeArray);

            var existingProcess = concurrentArray.EstablishGrowArrayProcess(growArrayProcess);

            existingProcess.Should().Be(null);
            concurrentArray.ReadGrowArrayProcessVolatile().Should().BeSameAs(growArrayProcess);
            spy.ExchangeArrayMustNotHaveBeenCalled();
        }
        public void AddAndRetrieveAll(Entry <int, string>[] entries)
        {
            var concurrentArray = new ConcurrentArrayBuilder <int, string>().Build();

            foreach (var entry in entries)
            {
                concurrentArray.TryAdd(entry);
            }

            foreach (var entry in entries)
            {
                var foundEntry = concurrentArray.Find(entry.HashCode, entry.Key);
                foundEntry.Should().BeSameAs(entry);
            }
        }
        public void GetExistingGrowArrayProcess()
        {
            var concurrentArray  = new ConcurrentArrayBuilder <Type, object>().Build();
            var newArraySize     = LinearDoublingPrimeStrategy.GetNextCapacity(concurrentArray.Capacity);
            var spy              = new ExchangeArraySpy <Type, object>();
            var growArrayProcess = new GrowArrayProcess <Type, object>(concurrentArray, newArraySize, spy.ExchangeArray);

            concurrentArray.EstablishGrowArrayProcess(growArrayProcess);

            var otherGrowArrayProcess = new GrowArrayProcess <Type, object>(concurrentArray, newArraySize, spy.ExchangeArray);
            var existingProcess       = concurrentArray.EstablishGrowArrayProcess(otherGrowArrayProcess);

            existingProcess.Should().BeSameAs(growArrayProcess);
            concurrentArray.ReadGrowArrayProcessVolatile().Should().BeSameAs(growArrayProcess);
        }
        public void Foreach()
        {
            var concurrentArray = new ConcurrentArrayBuilder <int, object>().WithCapacity(5)
                                  .Build()
                                  .FillArray();

            var readNumbers = new List <int>();

            foreach (var entry in concurrentArray)
            {
                readNumbers.Add(entry.Key);
            }

            readNumbers.Should().Contain(Enumerable.Range(0, 5));
        }
        public void FindWhenArrayIsFull(int targetKey, bool shouldBeFound)
        {
            var concurrentArray = new ConcurrentArrayBuilder <int, object>().WithCapacity(3)
                                  .Build()
                                  .FillArray();

            var foundEntry = concurrentArray.Find(targetKey.GetHashCode(), targetKey);

            if (shouldBeFound)
            {
                foundEntry.Key.Should().Be(targetKey);
            }
            else
            {
                foundEntry.Should().BeNull();
            }
        }
        public void CountMustBeZeroAtBeginning()
        {
            var concurrentArray = new ConcurrentArrayBuilder <uint, string>().Build();

            concurrentArray.Count.Should().Be(0);
        }