Пример #1
0
        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);
            }
        }
Пример #2
0
 private Trie[] realloc(Trie[] table, short size, bool ended)
 {
     return Utils.Realloc(table, size, ended);
 }
Пример #3
0
        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));
            }
        }
Пример #4
0
        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();
        }
Пример #5
0
        //  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);
        }