Exemplo n.º 1
0
        public IntSet Optimize(IntSet dontcare, bool mergeRuns = true)
        {
            if (dontcare == null)
            {
                return(this);
            }
            var dcRanges = dontcare.Runs();

            bool optimized = false;
            InternalList <IntRange> output = InternalList <IntRange> .Empty;

            for (int i = 0, dci = 0; i < _ranges.Count; i++)
            {
                IntRange r = _ranges[i];
                IntRange dc;
                for (;; dci++)
                {
                    if ((uint)dci >= (uint)dcRanges.Count)
                    {
                        // No more runs in dontcare
                        if (optimized)
                        {
                            goto next;
                        }
                        else
                        {
                            return(this);
                        }
                    }
                    dc = dcRanges[dci];
                    if (dc.Hi >= r.Lo)
                    {
                        break;
                    }
                }
                if (dc.Lo <= r.Hi)
                {
                    Debug.Assert(dc.Overlaps(r));
                    if (dc.Intersection(r) == r)
                    {
                        optimized = true;
                        continue;                         // omit r from output
                    }
                    else if (mergeRuns && i + 1 < _ranges.Count)
                    {
                        var r2 = _ranges[i + 1];
                        if (dc.Overlaps(r2))
                        {
                            optimized = true;
                            r         = new IntRange(r.Lo, r2.Hi);
                            i++;                             // omit _ranges[i+1] from output
                        }
                    }
                }
next:
                output.Add(r);
            }
            if (optimized)
            {
                return(New(this, IsInverted, output));
            }
            return(this);
        }