Пример #1
0
        /// <summary>
        /// Read an edge from the storage device using ginen index (offset/Id) and return the same.
        /// 1. Read the serialized data from storage.
        /// 2. De-serialize it back to IEdge.
        /// 3. Return the edge
        /// </summary>
        /// <param name="index">Index / Id / Key of the required edge</param>
        /// <returns>Edge found with given Key</returns>
        public IPersistentEdge Read(long index)
        {
            StringBuilder lineBuilder = new StringBuilder();

            byte[] buffer = null;

            lock (lockObject)
            {
                _stream.Seek(index, SeekOrigin.Begin);

                buffer = new byte[BUFFER_SIZE];
                _stream.Read(buffer, 0, BUFFER_SIZE);
            }

            for (int counter = 0; counter < BUFFER_SIZE; counter++)
            {
                if ((buffer[counter] == '\0') ||
                    (buffer[counter] == '\r') ||
                    (buffer[counter] == '\n'))
                {
                    break;
                }

                lineBuilder.Append((char)buffer[counter]);
            }

            IPersistentEdge edge = new PersistentMultiWaySuffixEdge(lineBuilder.ToString());

            edge.Key = index;
            return(edge);
        }
Пример #2
0
        /// <summary>
        /// Find the child edge, whose first character starts with given character.
        /// </summary>
        /// <param name="edge">Parent edge</param>
        /// <param name="character">First character of required edge</param>
        /// <returns>Edge found</returns>
        public override IEdge Find(IEdge edge, byte character)
        {
            PersistentMultiWaySuffixEdge pmwCurrentEdge = edge as PersistentMultiWaySuffixEdge;

            if (pmwCurrentEdge == null)
            {
                return(base.Find(edge, character));
            }

            // Find from the storage
            IEdge edgeFound = null;
            PersistentMultiWaySuffixEdge pmwEdge = null;
            int charIndex = 0;

            for (int index = 0; index < pmwCurrentEdge.GetChildren().Length; index++)
            {
                if (pmwCurrentEdge.GetChildren()[index] != -1)
                {
                    pmwEdge   = (PersistentMultiWaySuffixEdge)EdgeStore.Read(pmwCurrentEdge.GetChildren()[index]);
                    charIndex = pmwEdge.StartIndex;

                    if (charIndex < Sequence.Count)
                    {
                        if ((Sequence as IList <byte>)[charIndex] == character)
                        {
                            edgeFound = pmwEdge;
                            break;
                        }
                    }
                }
            }

            return(edgeFound);
        }
Пример #3
0
        /// <summary>
        /// Remove the edge from tree, this requires bubbling all the child edges one level up.
        /// </summary>
        /// <param name="parentEdge">Parent edge.</param>
        /// <param name="edge">Edge to be removed.</param>
        /// <returns></returns>
        public override bool Remove(IEdge parentEdge, IEdge edge)
        {
            PersistentMultiWaySuffixEdge pmwParentEdge = parentEdge as PersistentMultiWaySuffixEdge;

            if (pmwParentEdge == null)
            {
                return(base.Remove(parentEdge, edge));
            }

            PersistentMultiWaySuffixEdge pmwedge = edge as PersistentMultiWaySuffixEdge;

            if (pmwedge == null)
            {
                throw new ArgumentNullException("edge");
            }

            // Find the edge
            // Set the children reference to -1;
            for (int index = 0; index < pmwParentEdge.GetChildren().Length; index++)
            {
                if (pmwParentEdge.GetChildren()[index] == pmwedge.Key)
                {
                    pmwParentEdge.GetChildren()[index] = -1;
                    EdgeStore.Write(pmwParentEdge);
                    EdgeStore.Remove(pmwedge.Key);
                    Count--;
                    return(true);
                }
            }

            return(false);
        }
Пример #4
0
        /// <summary>
        /// Insert a edge at given parent.
        /// </summary>
        /// <param name="parentEdge">Parent edge.</param>
        /// <param name="startIndex">Start index of edge</param>
        /// <param name="endIndex">End index of edge</param>
        /// <returns>New edge created</returns>
        public override IEdge Insert(IEdge parentEdge, int startIndex, int endIndex)
        {
            // This is a leaf node with both start and end indices pointing to
            // terminating symbol. Don't insert this.
            if (startIndex >= Sequence.Count)
            {
                return(null);
            }

            if (PersisntThreshold > Count)
            {
                return(base.Insert(parentEdge, startIndex, endIndex));
            }

            PersistentMultiWaySuffixEdge edge = new PersistentMultiWaySuffixEdge(
                startIndex,
                endIndex,
                MaximumChildrenCount);

            edge.Key = EdgeStore.Write(edge);

            // Parent edge of type PersistentMultiWaySuffixEdge
            PersistentMultiWaySuffixEdge pmwParentEdge = parentEdge as PersistentMultiWaySuffixEdge;

            if (pmwParentEdge != null)
            {
                pmwParentEdge.AddChild(edge.Key);
                Count++;
                return(edge);
            }

            // Parent edge of type MultiWaySuffixEdge
            MultiWaySuffixEdge mwParentEdge = parentEdge as MultiWaySuffixEdge;

            if (mwParentEdge != null)
            {
                if (mwParentEdge.GetChildren() == null)
                {
                    mwParentEdge.AddChild(edge);
                    Count++;
                    return(edge);
                }

                if (mwParentEdge.GetChildren().Length < MaximumChildrenCount)
                {
                    mwParentEdge.AddChild(edge);
                    Count++;
                    return(edge);
                }

                // No more children edge can be added.
                throw new InvalidOperationException(string.Format(
                                                        CultureInfo.CurrentCulture,
                                                        "Cannot add more than {0} child nodes to edge.",
                                                        MaximumChildrenCount));
            }

            return(edge);
        }
Пример #5
0
        public override IEdge Split(IEdge edge, int splitAt)
        {
            // This is a leaf node with both start and end indices pointing to
            // terminating symbol. Don't insert this.
            if (splitAt == Sequence.Count)
            {
                return(edge);
            }

            PersistentMultiWaySuffixEdge pmwCurrentEdge = edge as PersistentMultiWaySuffixEdge;

            if (pmwCurrentEdge == null)
            {
                return(base.Split(edge, splitAt));
            }

            // Create the new edge
            PersistentMultiWaySuffixEdge newEdge =
                new PersistentMultiWaySuffixEdge(splitAt + 1, pmwCurrentEdge.EndIndex, MaximumChildrenCount);

            // Copy the children of old edge to new edge
            newEdge.ReplaceChildren(pmwCurrentEdge.GetChildren());

            // Write the edge to storage
            newEdge.Key = EdgeStore.Write(newEdge);

            // Update the old edge
            pmwCurrentEdge.EndIndex = splitAt;

            // Set new edge as child edge to old edge
            pmwCurrentEdge.ClearChildren();
            pmwCurrentEdge.AddChild(newEdge.Key);
            Count++;

            // Update the edge in storage
            EdgeStore.Write(pmwCurrentEdge);

            return(pmwCurrentEdge);
        }
Пример #6
0
        /// <summary>
        /// Update the old node with new node, requires merging the child edges.
        /// </summary>
        /// <param name="parentEdge">Parent edge.</param>
        /// <param name="oldEdge">Old edge</param>
        /// <param name="newEdge">new edge</param>
        /// <returns></returns>
        public override bool Update(IEdge parentEdge, IEdge oldEdge, IEdge newEdge)
        {
            PersistentMultiWaySuffixEdge pmwParentEdge = parentEdge as PersistentMultiWaySuffixEdge;

            if (pmwParentEdge == null)
            {
                return(base.Update(parentEdge, oldEdge, newEdge));
            }

            PersistentMultiWaySuffixEdge pmwOldEdge = oldEdge as PersistentMultiWaySuffixEdge;

            if (pmwOldEdge == null)
            {
                throw new ArgumentNullException("oldEdge");
            }

            PersistentMultiWaySuffixEdge pmwNewEdge = newEdge as PersistentMultiWaySuffixEdge;

            if (pmwNewEdge == null)
            {
                throw new ArgumentNullException("newEdge");
            }

            // Find the edge
            // Replace the edge
            for (int index = 0; index < pmwParentEdge.GetChildren().Length; index++)
            {
                if (pmwParentEdge.GetChildren()[index] == pmwOldEdge.Key)
                {
                    pmwParentEdge.GetChildren()[index] = pmwNewEdge.Key;
                    EdgeStore.Write(pmwParentEdge);
                    return(true);
                }
            }

            return(false);
        }