The Row class represents a row in a matrix representation of a Trie.
示例#1
0
        /// <summary>
        /// Add the given key associated with the given patch command. If either
        /// parameter is null this method will return without executing.
        /// </summary>
        /// <param name="key">the key</param>
        /// <param name="cmd">the patch command</param>
        public virtual void Add(string key, string cmd)
        {
            if (key == null || cmd == null)
            {
                return;
            }
            if (cmd.Length == 0)
            {
                return;
            }
            int id_cmd = cmds.IndexOf(cmd);
            if (id_cmd == -1)
            {
                id_cmd = cmds.Count;
                cmds.Add(cmd);
            }

            int node = root;
            Row r = GetRow(node);

            StrEnum e = new StrEnum(key, forward);

            for (int i = 0; i < e.Length - 1; i++)
            {
                char ch = e.Next();
                node = r.GetRef(ch);
                if (node >= 0)
                {
                    r = GetRow(node);
                }
                else
                {
                    node = rows.Count;
                    Row n;
                    rows.Add(n = new Row());
                    r.SetRef(ch, node);
                    r = n;
                }
            }
            r.SetCmd(e.Next(), id_cmd);
        }
示例#2
0
 /// <summary>
 /// Construct a <see cref="Row"/> using the cells of the given <see cref="Row"/>.
 /// </summary>
 /// <param name="old">the <see cref="Row"/> to copy</param>
 public Row(Row old)
 {
     cells = old.cells;
 }
示例#3
0
 /// <summary>
 /// Test whether the given Row of Cells in a Trie should be included in an
 /// optimized Trie.
 /// </summary>
 /// <param name="in">the Row to test</param>
 /// <param name="remap">Description of the Parameter</param>
 /// <returns><c>true</c> if the Row should remain; otherwise, <c>false</c></returns>
 public bool Eat(Row @in, int[] remap)
 {
     int sum = 0;
     for (IEnumerator<Cell> i = @in.cells.Values.GetEnumerator(); i.MoveNext();)
     {
         Cell c = i.Current;
         sum += c.cnt;
         if (c.@ref >= 0)
         {
             if (remap[c.@ref] == 0)
             {
                 c.@ref = -1;
             }
         }
     }
     int frame = sum / 10;
     bool live = false;
     for (IEnumerator<Cell> i = @in.cells.Values.GetEnumerator(); i.MoveNext();)
     {
         Cell c = i.Current;
         if (c.cnt < frame && c.cmd >= 0)
         {
             c.cnt = 0;
             c.cmd = -1;
         }
         if (c.cmd >= 0 || c.@ref >= 0)
         {
             live |= true;
         }
     }
     return !live;
 }
示例#4
0
        /// <summary>
        /// Merge the given rows and return the resulting <see cref="Row"/>.
        /// </summary>
        /// <param name="master">the master <see cref="Row"/></param>
        /// <param name="existing">the existing <see cref="Row"/></param>
        /// <returns>the resulting <see cref="Row"/>, or <c>null</c> if the operation cannot be realized</returns>
        public Row Merge(Row master, Row existing)
        {
            var i = master.cells.Keys.GetEnumerator();
            Row n = new Row();
            for (; i.MoveNext();)
            {
                char ch = i.Current;
                // XXX also must handle Cnt and Skip !!
                Cell a = master.cells.ContainsKey(ch) ? master.cells[ch] : null;
                Cell b = existing.cells.ContainsKey(ch) ? existing.cells[ch] : null;

                Cell s = (b == null) ? new Cell(a) : Merge(a, b);
                if (s == null)
                {
                    return null;
                }
                n.cells[ch] = s;
            }
            i = existing.cells.Keys.GetEnumerator();
            for (; i.MoveNext();)
            {
                char ch = i.Current;
                if (master.At(ch) != null)
                {
                    continue;
                }
                n.cells[ch] = existing.At(ch);
            }
            return n;
        }
示例#5
0
 /// <summary>
 /// Reduce the trie using Lift-Up reduction.
 /// <para>
 /// The Lift-Up reduction propagates all leaf-values (patch commands), where
 /// possible, to higher levels which are closer to the root of the trie.
 /// </para>
 /// </summary>
 /// <param name="in">the Row to consider when optimizing</param>
 /// <param name="nodes">contains the patch commands</param>
 public void LiftUp(Row @in, IList<Row> nodes)
 {
     IEnumerator<Cell> i = @in.cells.Values.GetEnumerator();
     for (; i.MoveNext();)
     {
         Cell c = i.Current;
         if (c.@ref >= 0)
         {
             Row to = nodes[c.@ref];
             int sum = to.UniformCmd(changeSkip);
             if (sum >= 0)
             {
                 if (sum == c.cmd)
                 {
                     if (changeSkip)
                     {
                         if (c.skip != to.uniformSkip + 1)
                         {
                             continue;
                         }
                         c.skip = to.uniformSkip + 1;
                     }
                     else
                     {
                         c.skip = 0;
                     }
                     c.cnt += to.uniformCnt;
                     c.@ref = -1;
                 }
                 else if (c.cmd < 0)
                 {
                     c.cnt = to.uniformCnt;
                     c.cmd = sum;
                     c.@ref = -1;
                     if (changeSkip)
                     {
                         c.skip = to.uniformSkip + 1;
                     }
                     else
                     {
                         c.skip = 0;
                     }
                 }
             }
         }
     }
 }