private NodeRecord _ReadNode
        (
            bool isLeaf,
            [NotNull] Stream stream,
            long offset
        )
        {
            stream.Position = offset;

            NodeRecord result = new NodeRecord(isLeaf)
            {
                _stream = stream,
                Leader  =
                {
                    Number     = stream.ReadInt32Network(),
                    Previous   = stream.ReadInt32Network(),
                    Next       = stream.ReadInt32Network(),
                    TermCount  = stream.ReadInt16Network(),
                    FreeOffset = stream.ReadInt16Network()
                }
            };

            for (int i = 0; i < result.Leader.TermCount; i++)
            {
                NodeItem item = new NodeItem
                {
                    Length     = stream.ReadInt16Network(),
                    KeyOffset  = stream.ReadInt16Network(),
                    LowOffset  = stream.ReadInt32Network(),
                    HighOffset = stream.ReadInt32Network()
                };
                result.Items.Add(item);
            }

            foreach (NodeItem item in result.Items)
            {
                stream.Position = offset + item.KeyOffset;
                byte[] buffer = stream.ReadBytes(item.Length);
                string text   = _encoding.GetString(buffer);
                item.Text = text;
            }

            return(result);
        }
        public TermLink[] SearchStart
        (
            [CanBeNull] string key
        )
        {
            List <TermLink> result = new List <TermLink>();

            if (string.IsNullOrEmpty(key))
            {
                return(new TermLink[0]);
            }

            key = key.ToUpperInvariant();

            NodeRecord firstNode   = ReadNode(1);
            NodeRecord rootNode    = ReadNode(firstNode.Leader.Number);
            NodeRecord currentNode = rootNode;

            NodeItem goodItem = null;

            while (true)
            {
                bool found  = false;
                bool beyond = false;

                foreach (NodeItem item in currentNode.Items)
                {
                    int compareResult = string.CompareOrdinal(item.Text, key);
                    if (compareResult > 0)
                    {
                        beyond = true;
                        break;
                    }

                    goodItem = item;
                    found    = true;
                }
                if (goodItem == null)
                {
                    break;
                }
                if (found)
                {
                    if (beyond || (currentNode.Leader.Next == -1))
                    {
                        if (goodItem.RefersToLeaf)
                        {
                            goto FOUND;
                        }
                        currentNode = ReadNode(goodItem.LowOffset);
                    }
                    else
                    {
                        currentNode = ReadNext(currentNode);
                    }
                }
                else
                {
                    if (goodItem.RefersToLeaf)
                    {
                        goto FOUND;
                    }
                    currentNode = ReadNode(goodItem.LowOffset);
                }
                //Console.WriteLine(currentNode);
            }

FOUND:
            if (goodItem != null)
            {
                currentNode = ReadLeaf(goodItem.LowOffset);
                while (true)
                {
                    foreach (NodeItem item in currentNode.Items)
                    {
                        int compareResult = string.CompareOrdinal(item.Text, key);
                        if (compareResult >= 0)
                        {
                            bool starts = item.Text.StartsWith(key);
                            if ((compareResult > 0) && !starts)
                            {
                                goto DONE;
                            }
                            if (starts)
                            {
                                IfpRecord ifp = ReadIfpRecord(item.FullOffset);
                                result.AddRange(ifp.Links);
                            }
                        }
                    }
                    if (currentNode.Leader.Next > 0)
                    {
                        currentNode = ReadNext(currentNode);
                    }
                }
            }

DONE:
            return(result
                   .Distinct()
                   .ToArray());
        }
        public TermLink[] SearchExact
        (
            [CanBeNull] string key
        )
        {
            if (string.IsNullOrEmpty(key))
            {
                return(new TermLink[0]);
            }

            key = key.ToUpperInvariant();

            NodeRecord firstNode   = ReadNode(1);
            NodeRecord rootNode    = ReadNode(firstNode.Leader.Number);
            NodeRecord currentNode = rootNode;

            NodeItem goodItem = null;

            while (true)
            {
                bool found  = false;
                bool beyond = false;

                foreach (NodeItem item in currentNode.Items)
                {
                    int compareResult = string.CompareOrdinal(item.Text, key);
                    if (compareResult > 0)
                    {
                        beyond = true;
                        break;
                    }

                    goodItem = item;
                    found    = true;

                    if ((compareResult == 0) &&
                        currentNode.IsLeaf)
                    {
                        goto FOUND;
                    }
                }
                if (goodItem == null)
                {
                    break;
                }
                if (found)
                {
                    if (beyond || (currentNode.Leader.Next == -1))
                    {
                        currentNode = goodItem.RefersToLeaf
                            ? ReadLeaf(goodItem.LowOffset)
                            : ReadNode(goodItem.LowOffset);
                    }
                    else
                    {
                        currentNode = ReadNext(currentNode);
                    }
                }
                else
                {
                    currentNode = goodItem.RefersToLeaf
                        ? ReadLeaf(goodItem.LowOffset)
                        : ReadNode(goodItem.LowOffset);
                }
                //Console.WriteLine(currentNode);
            }

FOUND:
            if (goodItem != null)
            {
                IfpRecord ifp = ReadIfpRecord(goodItem.FullOffset);
                return(ifp.Links.ToArray());
            }

            return(new TermLink[0]);
        }
Example #4
0
        public TermLink[] SearchExact
        (
            [CanBeNull] string key
        )
        {
            if (string.IsNullOrEmpty(key))
            {
                return(new TermLink[0]);
            }

            try
            {
                key = key.ToUpperInvariant();

                NodeRecord firstNode   = ReadNode(1);
                NodeRecord rootNode    = ReadNode(firstNode.Leader.Number);
                NodeRecord currentNode = rootNode;

                NodeItem goodItem = null;
                while (true)
                {
                    bool found  = false;
                    bool beyond = false;

                    foreach (NodeItem item in currentNode.Items)
                    {
                        int compareResult = string.CompareOrdinal(item.Text, key);
                        if (compareResult > 0)
                        {
                            beyond = true;
                            break;
                        }

                        goodItem = item;
                        found    = true;

                        if (compareResult == 0 &&
                            currentNode.IsLeaf)
                        {
                            goto FOUND;
                        }
                    }
                    if (goodItem == null)
                    {
                        break;
                    }
                    if (found)
                    {
                        if (beyond || currentNode.Leader.Next == -1)
                        {
                            currentNode = goodItem.RefersToLeaf
                                ? ReadLeaf(goodItem.LowOffset)
                                : ReadNode(goodItem.LowOffset);
                        }
                        else
                        {
                            currentNode = ReadNext(currentNode);
                        }
                    }
                    else
                    {
                        currentNode = goodItem.RefersToLeaf
                            ? ReadLeaf(goodItem.LowOffset)
                            : ReadNode(goodItem.LowOffset);
                    }
                    //Console.WriteLine(currentNode);
                }

FOUND:
                if (goodItem != null)
                {
                    // ibatrak записи могут иметь ссылки на следующие

                    List <TermLink> result = new List <TermLink>();
                    long            offset = goodItem.FullOffset;
                    while (offset > 0)
                    {
                        IfpRecord ifp = ReadIfpRecord(offset);
                        result.AddRange(ifp.Links);
                        offset = ifp.FullOffset > 0
                            ? ifp.FullOffset
                            : 0;
                    }

                    return(result
                           .Distinct()
                           .ToArray());
                    //ibatrak до сюда
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }

            return(new TermLink[0]);
        }