public bool Add(byte[] prefix, int start) { // We are at the node corresponding to the prefix. We are done. if (prefix == null || prefix.Length == start) { ++m_refcnt; return m_refcnt == 1; } byte c = prefix[start]; if (c < m_min || c >= m_min + m_count) { // The character is out of range of currently handled // charcters. We have to extend the table. if (m_count == 0) { m_min = c; m_count = 1; m_next = null; } else if (m_count == 1) { byte oldc = m_min; Trie oldp = m_next[0]; m_count = (short)((m_min < c ? c - m_min : m_min - c) + 1); m_next = new Trie[m_count]; m_min = Math.Min(m_min, c); m_next[oldc - m_min] = oldp; } else if (m_min < c) { // The new character is above the current character range. m_count = (short)(c - m_min + 1); m_next = realloc(m_next, m_count, true); } else { // The new character is below the current character range. m_count = (short)((m_min + m_count) - c); m_next = realloc(m_next, m_count, false); m_min = c; } } // If next node does not exist, create one. if (m_count == 1) { if (m_next == null) { m_next = new Trie[1]; m_next[0] = new Trie(); ++m_liveNodes; //alloc_Debug.Assert(next.node); } return m_next[0].Add(prefix, start + 1); } else { if (m_next[c - m_min] == null) { m_next[c - m_min] = new Trie(); ++m_liveNodes; //alloc_Debug.Assert(next.table [c - min]); } return m_next[c - m_min].Add(prefix, start + 1); } }
private Trie[] realloc(Trie[] table, short size, bool ended) { return Utils.Realloc(table, size, ended); }
public bool Add(byte[] prefix, int start) { // We are at the node corresponding to the prefix. We are done. if (prefix == null || prefix.Length == start) { ++m_refcnt; return(m_refcnt == 1); } byte c = prefix[start]; if (c < m_min || c >= m_min + m_count) { // The character is out of range of currently handled // charcters. We have to extend the table. if (m_count == 0) { m_min = c; m_count = 1; m_next = null; } else if (m_count == 1) { byte oldc = m_min; Trie oldp = m_next[0]; m_count = (short)((m_min < c ? c - m_min : m_min - c) + 1); m_next = new Trie[m_count]; m_min = Math.Min(m_min, c); m_next[oldc - m_min] = oldp; } else if (m_min < c) { // The new character is above the current character range. m_count = (short)(c - m_min + 1); m_next = realloc(m_next, m_count, true); } else { // The new character is below the current character range. m_count = (short)((m_min + m_count) - c); m_next = realloc(m_next, m_count, false); m_min = c; } } // If next node does not exist, create one. if (m_count == 1) { if (m_next == null) { m_next = new Trie[1]; m_next[0] = new Trie(); ++m_liveNodes; //alloc_Debug.Assert(next.node); } return(m_next[0].Add(prefix, start + 1)); } else { if (m_next[c - m_min] == null) { m_next[c - m_min] = new Trie(); ++m_liveNodes; //alloc_Debug.Assert(next.table [c - min]); } return(m_next[c - m_min].Add(prefix, start + 1)); } }
public XSub(Ctx parent, int tid, int sid) : base(parent, tid, sid) { m_options.SocketType = ZmqSocketType.Xsub; m_hasMessage = false; m_more = false; m_options.Linger = 0; m_fq = new FQ(); m_dist = new Dist(); m_subscriptions = new Trie(); }
// Remove key from the trie. Returns true if the item is actually // removed from the trie. public bool Remove(byte[] prefix, int start) { if (prefix == null || prefix.Length == start) { if (m_refcnt == 0) { return(false); } m_refcnt--; return(m_refcnt == 0); } byte c = prefix[start]; if (m_count == 0 || c < m_min || c >= m_min + m_count) { return(false); } Trie nextNode = m_count == 1 ? m_next[0] : m_next[c - m_min]; if (nextNode == null) { return(false); } bool ret = nextNode.Remove(prefix, start + 1); if (nextNode.IsRedundant()) { //delete next_node; 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 Trie node = null; for (short i = 0; i < m_count; ++i) { if (m_next[i] != null) { node = m_next[i]; m_min = (byte)(i + m_min); break; } } Debug.Assert(node != null); //free (next.table); m_next = null; m_next = new Trie[] { node }; m_count = 1; } else if (c == m_min) { // We can compact the table "from the left" byte newMin = m_min; for (short i = 1; i < m_count; ++i) { if (m_next[i] != null) { newMin = (byte)(i + m_min); break; } } Debug.Assert(newMin != m_min); Debug.Assert(newMin > m_min); Debug.Assert(m_count > newMin - m_min); m_count = (short)(m_count - (newMin - m_min)); m_next = realloc(m_next, m_count, true); m_min = newMin; } else if (c == m_min + m_count - 1) { // We can compact the table "from the right" short newCount = m_count; for (short i = 1; i < m_count; ++i) { if (m_next[m_count - 1 - i] != null) { newCount = (short)(m_count - i); break; } } Debug.Assert(newCount != m_count); m_count = newCount; m_next = realloc(m_next, m_count, false); } } } return(ret); }