Ejemplo n.º 1
0
 public CustomSet <T> Except(CustomSet <T> other)
 {
     if (factory != other.factory)
     {
         throw new NotImplementedException();
     }
     if (other.set.Length == 0)
     {
         return(this);
     }
     if (other.set[0] > set[^ 1])
     {
         return(this);
     }
     if (other.set[^ 1] < set[0])
Ejemplo n.º 2
0
        public static List <HashSet <IModContext <TMod, TModGetter, IMajorRecordCommon, IMajorRecordCommonGetter> > > PatchesFromRecordSets <TMod, TModGetter>(Dictionary <CustomSet <ModKey>, RecordsClassifiedByMasters <TMod, TModGetter> > recordSets, CustomSetFactory <ModKey> setFactory, int maximumMastersPerMod = MAXIMUM_MASTERS_PER_MOD)
            where TMod : class, IMod, TModGetter
            where TModGetter : class, IModGetter, IMajorRecordContextEnumerable <TMod, TModGetter>
        {
            var patches = new List <HashSet <IModContext <TMod, TModGetter, IMajorRecordCommon, IMajorRecordCommonGetter> > >();

            bool newRecordsFirst = true;

            var temp         = setFactory.NewSet();
            var smallestSets = new Dictionary <CustomSet <ModKey>, NewStruct2>();

            while (recordSets.Count > 0)
            {
                temp.Clear();
                int largestMasterSetCount           = 0;
                CustomSet <ModKey> largestMasterSet = null !;

                foreach (var(masterSet, data) in recordSets)
                {
                    if (newRecordsFirst)
                    {
                        if (!data.hasNewRecords)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        temp.UnionWith(masterSet);
                    }

                    if (largestMasterSet is null || data.MasterCount > largestMasterSetCount)
                    {
                        largestMasterSetCount = data.MasterCount;
                        largestMasterSet      = masterSet;
                    }
                }

                if (largestMasterSet is null)
                {
                    newRecordsFirst = false;
                    continue;
                }

                if (!newRecordsFirst)
                {
                    if (temp.Count <= maximumMastersPerMod)
                    {
                        var patchContents = new HashSet <IModContext <TMod, TModGetter, IMajorRecordCommon, IMajorRecordCommonGetter> >();
                        foreach (var(masterSet, data) in recordSets)
                        {
                            patchContents.UnionWith(data.contextSet);
                        }
                        recordSets.Clear();
                        patches.Add(patchContents);
                        continue;
                    }
                }

                var largestMasterRecordSet = recordSets[largestMasterSet];
                recordSets.Remove(largestMasterSet);

                while (recordSets.Count > 0)
                {
                    int smallestAdditionalMasterSetCount = 0;
                    CustomSet <ModKey> smallestMasterSet = null !;
                    smallestSets.Clear();
                    foreach (var(masterSet, data) in recordSets)
                    {
                        if (newRecordsFirst)
                        {
                            if (!data.hasNewRecords)
                            {
                                continue;
                            }
                        }

                        // the set of distinct masterRecords that would be added to our current target if we added this recordSet to the mix.

                        var temp2 = masterSet.Except(largestMasterSet);

                        int additionalMasterCount = temp2.Count;

                        if (additionalMasterCount == smallestAdditionalMasterSetCount)
                        {
                            var foo = smallestSets.Autovivify(temp2, () => new(0, new()));
                            foo.recordCount += data.contextSet.Count;
                            foo.masterSets.Add(masterSet);
                        }

                        if (smallestMasterSet is null || additionalMasterCount < smallestAdditionalMasterSetCount)
                        {
                            smallestSets.Clear();
                            smallestSets[temp.ToCustomSet()] = new(data.contextSet.Count, new() { masterSet });
                            smallestAdditionalMasterSetCount = additionalMasterCount;
                            smallestMasterSet = masterSet;
                        }
                    }

                    if (smallestMasterSet is null)
                    {
                        newRecordsFirst = false;
                        continue;
                    }

                    if (smallestAdditionalMasterSetCount == 0)
                    {
                        foreach (var(_, (_, masterSets)) in smallestSets)
                        {
                            foreach (var masterSet in masterSets)
                            {
                                var recordSet = recordSets[masterSet];
                                recordSets.Remove(masterSet);

                                largestMasterRecordSet.contextSet.UnionWith(recordSet.contextSet);
                            }
                        }
                    }
                    else
                    {
                        int newMasterCount = largestMasterSetCount + smallestAdditionalMasterSetCount;

                        if (newMasterCount > maximumMastersPerMod)
                        {
                            break;
                        }

                        largestMasterSetCount = newMasterCount;

                        int maxCount = 0;
                        HashSet <CustomSet <ModKey> > victim = null !;

                        foreach (var(id, (count, masterSets)) in smallestSets)
                        {
                            if (victim is null || count > maxCount)
                            {
                                maxCount = count;
                                victim   = masterSets;
                            }
                        }

                        foreach (var masterSet in victim)
                        {
                            var recordSet = recordSets[masterSet];
                            recordSets.Remove(masterSet);

                            largestMasterRecordSet.contextSet.UnionWith(recordSet.contextSet);
                        }
                    }
                }
                newRecordsFirst = false;
                patches.Add(largestMasterRecordSet.contextSet);
            }


            return(patches);
        }