protected override bool XSend(ref Msg msg, SendReceiveOptions flags) { byte[] data = msg.Data; int size = msg.Size; if (size > 0 && data[0] == 1) { // Process the subscription. if (m_subscriptions.Add(data, 1, size - 1)) { m_dist.SendToAll(ref msg, flags); return(true); } } else if (size > 0 && data[0] == 0) { if (m_subscriptions.Remove(data, 1, size - 1)) { m_dist.SendToAll(ref msg, flags); return(true); } } else { // upstream message unrelated to sub/unsub m_dist.SendToAll(ref msg, flags); return(true); } msg.Close(); msg.InitEmpty(); return(true); }
protected override bool XSend(Msg msg, SendReceiveOptions flags) { byte[] data = msg.Data; // Malformed subscriptions. if (data.Length < 1 || (data[0] != 0 && data[0] != 1)) { throw InvalidException.Create(); } // Process the subscription. if (data[0] == 1) { if (m_subscriptions.Add(data, 1)) { m_dist.SendToAll(msg, flags); } } else { if (m_subscriptions.Remove(data, 1)) { m_dist.SendToAll(msg, flags); } } return(true); }
// 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); }