Beispiel #1
0
        private bool RemovemHelper(byte[] prefix, int start, byte[] pipe)
        {
            if (prefix == null || prefix.Length == start)
            {
                if (m_pipes != null)
                {
                    bool erased = m_pipes.Remove(pipe);
                    Debug.Assert(erased);
                    if (m_pipes.Count == 0)
                    {
                        m_pipes = null;
                    }
                }
                return(m_pipes == null);
            }

            byte c = prefix[start];

            if (m_count == 0 || c < m_min || c >= m_min + m_count)
            {
                return(false);
            }

            Mtrie nextNode =
                m_count == 1 ? m_next[0] : m_next[c - m_min];

            if (nextNode == null)
            {
                return(false);
            }

            bool ret = nextNode.RemovemHelper(prefix, start + 1, pipe);

            if (nextNode.IsRedundant)
            {
                Debug.Assert(m_count > 0);

                if (m_count == 1)
                {
                    m_next  = null;
                    m_count = 0;
                    --m_liveNodes;
                    Debug.Assert(m_liveNodes == 0);
                }
                else
                {
                    m_next[c - m_min] = null;
                    Debug.Assert(m_liveNodes > 1);
                    --m_liveNodes;

                    //  Compact the table if possible
                    if (m_liveNodes == 1)
                    {
                        //  If there's only one live node in the table we can
                        //  switch to using the more compact single-node
                        //  representation
                        int i;
                        for (i = 0; i < m_count; ++i)
                        {
                            if (m_next[i] != null)
                            {
                                break;
                            }
                        }

                        Debug.Assert(i < m_count);
                        m_min  += i;
                        m_count = 1;
                        Mtrie old = m_next[i];
                        m_next = new Mtrie[] { old };
                    }
                    else if (c == m_min)
                    {
                        //  We can compact the table "from the left"
                        int i;
                        for (i = 1; i < m_count; ++i)
                        {
                            if (m_next[i] != null)
                            {
                                break;
                            }
                        }

                        Debug.Assert(i < m_count);
                        m_min   += i;
                        m_count -= i;
                        m_next   = Realloc(m_next, m_count, false);
                    }
                    else if (c == m_min + m_count - 1)
                    {
                        //  We can compact the table "from the right"
                        int i;
                        for (i = 1; i < m_count; ++i)
                        {
                            if (m_next[m_count - 1 - i] != null)
                            {
                                break;
                            }
                        }
                        Debug.Assert(i < m_count);
                        m_count -= i;
                        m_next   = Realloc(m_next, m_count, true);
                    }
                }
            }

            return(ret);
        }