Exemplo n.º 1
0
        private async Task <IList <ArmorSetSearchResult> > SearchArmorSetsInternal(
            ISolverData data,
            CancellationToken cancellationToken
            )
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(null);
            }

            var heads     = new List <IArmorPiece>();
            var chests    = new List <IArmorPiece>();
            var gloves    = new List <IArmorPiece>();
            var waists    = new List <IArmorPiece>();
            var legs      = new List <IArmorPiece>();
            var allCharms = new List <ICharmLevel>();

            var results = new List <ArmorSetSearchResult>();

            var generator = new EquipmentCombinationGenerator(
                searchEquipmentsObjectPool,
                data.AllHeads.Where(x => x.IsSelected).Select(x => x.Equipment),
                data.AllChests.Where(x => x.IsSelected).Select(x => x.Equipment),
                data.AllGloves.Where(x => x.IsSelected).Select(x => x.Equipment),
                data.AllWaists.Where(x => x.IsSelected).Select(x => x.Equipment),
                data.AllLegs.Where(x => x.IsSelected).Select(x => x.Equipment),
                data.AllCharms.Where(x => x.IsSelected).Select(x => x.Equipment)
                );

            long hh = data.AllHeads.Count(x => x.IsSelected);
            long cc = data.AllChests.Count(x => x.IsSelected);
            long gg = data.AllGloves.Count(x => x.IsSelected);
            long ww = data.AllWaists.Count(x => x.IsSelected);
            long ll = data.AllLegs.Count(x => x.IsSelected);
            long ch = data.AllCharms.Count(x => x.IsSelected);

            long combinationCount =
                Math.Max(hh, 1) *
                Math.Max(cc, 1) *
                Math.Max(gg, 1) *
                Math.Max(ww, 1) *
                Math.Max(ll, 1) *
                Math.Max(ch, 1);

            await Task.Yield();

            var parallelOptions = new ParallelOptions
            {
                //MaxDegreeOfParallelism = 1, // to ease debugging
                MaxDegreeOfParallelism = Environment.ProcessorCount
            };

            currentCombinations = 0;
            totalCombinations   = combinationCount;

            ParallelLoopResult parallelResult;

            try
            {
                const int batchSize = 4096;

                using (var equipmentBatchObjectPool = new ObjectPool <EquipmentBatch>(() => EquipmentBatch.Create(batchSize)))
                {
                    OrderablePartitioner <EquipmentBatch> partitioner = Partitioner.Create(generator.AllBatch(equipmentBatchObjectPool, cancellationToken), EnumerablePartitionerOptions.NoBuffering);

                    parallelResult = Parallel.ForEach(partitioner, parallelOptions, equipmentBatch =>
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            equipmentBatchObjectPool.PutObject(equipmentBatch);
                            return;
                        }

                        for (int i = 0; i < equipmentBatch.Size; i++)
                        {
                            EvaluateArmorSet(equipmentBatch.Equipment[i], data, results);
                        }

                        equipmentBatchObjectPool.PutObject(equipmentBatch);
                    });
                }
            }
            finally
            {
                generator.Reset();
            }

            return(results);
        }