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); }