Example #1
0
        public void CreateDatapool <T>(IDatapoolMetatdata <T> datapoolMetadata) where T : class
        {
            if (datapoolMetadata == null)
            {
                throw new ArgumentNullException("datapoolMetadata");
            }

            DatapoolManager.BuildDatapool(datapoolMetadata);
        }
        public void BuildDatapool <T>(IDatapoolMetatdata <T> metadata) where T : class
        {
            var datapool = new Datapool <T>(GrinderContext, metadata);

            spinLocked.DoLocked(
                () =>
            {
                if (datapools.ContainsKey(metadata.Name))
                {
                    throw new ArgumentException(string.Format("Duplicate datapool: '{0}'", metadata.Name));
                }

                datapools.Add(metadata.Name, datapool);
            });
        }
Example #3
0
        public Datapool(IGrinderContext grinderContext, IDatapoolMetatdata <T> datapoolMetadata)
        {
            if (grinderContext == null)
            {
                throw new ArgumentNullException("grinderContext");
            }

            if (datapoolMetadata == null)
            {
                throw new ArgumentNullException("datapoolMetadata");
            }

            GrinderContext   = grinderContext;
            distributionMode = datapoolMetadata.DistributionMode;
            PhysicalSize     = datapoolMetadata.Values.Count;

            int minCapacity;
            int agentCount    = int.Parse(GrinderContext.GetProperty(Constants.AgentCountKey, "1"));
            int processCount  = int.Parse(GrinderContext.GetProperty(Constants.ProcessCountKey, "1"));
            int agentOffset   = GrinderContext.AgentNumber;
            int processOffset = GrinderContext.ProcessNumber - GrinderContext.FirstProcessNumber;

            threadCount = int.Parse(GrinderContext.GetProperty(Constants.ThreadCountKey, "1"));
            if (distributionMode == DatapoolThreadDistributionMode.ThreadUnique)
            {
                if (!(agentCount > GrinderContext.AgentNumber))
                {
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Cannot ceate thread unique datapool '{0}', because property '{1}' = '{2}'. Current AgentNumber = '{3}' and indicates that '{1}' must be at least '{4}' for thread uniqueness to work correctly", datapoolMetadata.Name, Constants.AgentCountKey, agentCount, GrinderContext.AgentNumber, GrinderContext.AgentNumber + 1));
                }

                if (processOffset < 0)
                {
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Cannot ceate thread unique datapool '{0}', because thread offset negative ({1}). FirstProcessNumber = {2}, ProcessNumber = {3}", datapoolMetadata.Name, processOffset, GrinderContext.FirstProcessNumber, GrinderContext.ProcessNumber));
                }

                if (!(processCount > processOffset))
                {
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Cannot ceate thread unique datapool '{0}', because thread offset = '{1}' is not less than property 'grinder.threads' = '{2}'. FirstProcessNumber = {3}, ProcessNumber = {4}", datapoolMetadata.Name, processOffset, processCount, GrinderContext.FirstProcessNumber, GrinderContext.ProcessNumber));
                }

                minCapacity = agentCount * processCount * threadCount;
            }
            else
            {
                minCapacity = 1;
            }

            if (PhysicalSize < minCapacity)
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "To low capacity for datapool '{0}', expected at least '{1}', but was '{2}'", datapoolMetadata.Name, minCapacity, PhysicalSize));
            }

            T[] values = datapoolMetadata.Values.ToArray();

            if (datapoolMetadata.IsRandom && PhysicalSize > 1)
            {
                var random = new Random(datapoolMetadata.Seed);
                for (int i = 0; i < PhysicalSize; i++)
                {
                    int swapWith = random.Next(PhysicalSize);
                    T   orgValue = values[i];
                    values[i]        = values[swapWith];
                    values[swapWith] = orgValue;
                }
            }

            Tuple <int, int> agentSlice   = GetSubtupleInTupleSlicedBy(agentOffset, new Tuple <int, int>(0, PhysicalSize - 1), agentCount);
            Tuple <int, int> processSlice = GetSubtupleInTupleSlicedBy(processOffset, agentSlice, processCount);

            if (distributionMode == DatapoolThreadDistributionMode.ThreadShared)
            {
                nonThreadUniqueValueBucket = new ValueBucket
                {
                    Values         = values,
                    Name           = datapoolMetadata.Name,
                    StartOffset    = 0,
                    EndOffset      = PhysicalSize - 1,
                    NextOffset     = -1,
                    IsThreadUnique = false,
                    IsCircular     = datapoolMetadata.IsCircular,
                    LogicalSize    = processSlice.Item2 - processSlice.Item1 + 1
                };
            }
            else
            {
                threadUniqueValueBuckets = new ValueBucket[threadCount];

                for (int i = 0; i < threadCount; i++)
                {
                    Tuple <int, int> threadSlice = distributionMode == DatapoolThreadDistributionMode.ThreadUnique ?
                                                   GetSubtupleInTupleSlicedBy(i, processSlice, threadCount) :
                                                   new Tuple <int, int>(0, PhysicalSize - 1);
                    threadUniqueValueBuckets[i] = new ValueBucket
                    {
                        Values         = values,
                        Name           = datapoolMetadata.Name,
                        StartOffset    = threadSlice.Item1,
                        EndOffset      = threadSlice.Item2,
                        NextOffset     = threadSlice.Item1 - 1,
                        IsThreadUnique = true,
                        IsCircular     = datapoolMetadata.IsCircular,
                        LogicalSize    = threadSlice.Item2 - threadSlice.Item1 + 1
                    };
                }
            }
        }