Example #1
0
        internal async ValueTask <MatchResult> FindBestMatch(ReadOnlyMemory <byte> key)
        {
            LTrieNodeStruct gn = await ReadNodeStruct();

            LTrieNodeStruct prev = default;

            if (key.Length == 0)
            {
                return(await CreateMatchResult(0, gn.GetInternalLinkObject(), gn, prev));
            }
            for (int i = 0; i < key.Length; i++)
            {
                LTrieNodeExternalLinkStruct externalLink = default;
                if (key.Span[i] == gn.FirstExternalLink.Value)
                {
                    externalLink = gn.FirstExternalLink;
                }
                else if (gn.ExternalLinkSlotCount > 1)
                {
                    externalLink = await GetRemainingExternalLink(gn, key.Span[i]);
                }
                if (externalLink.Pointer == 0)
                {
                    var result = await CreateMatchResult(i, null, gn, prev);

                    result.MissingValue = key.Span[i];
                    result.KeyIndex     = i;
                    return(result);
                }
                if (!externalLink.LinkToNode)
                {
                    var result = await CreateMatchResult(i, externalLink.ToLinkObject(), gn, prev);

                    result.KeyIndex = i;
                    return(result);
                }
                prev = gn;
                gn   = await ReadNodeStruct(externalLink.Pointer);
            }
            return(await CreateMatchResult(key.Length, gn.GetInternalLinkObject(), gn, prev));
        }
Example #2
0
        private async ValueTask <LTrieNode> ToLTrieNodeObject(LTrieNodeStruct nodeStruct, int minKeyLength)
        {
            LTrieNode?cached = null;

            NodeCache?.TryGetValue(nodeStruct.OwnPointer, out cached);
            if (cached is LTrieNode)
            {
                if (cached.MinKeyLength != minKeyLength)
                {
                    throw new InvalidOperationException("Inconsistent depth, bug in DBTrie");
                }
                if (cached.OwnPointer != nodeStruct.OwnPointer)
                {
                    throw new InvalidOperationException("Inconsistent pointer in cache, bug in DBTrie");
                }
                await cached.AssertConsistency();

                return(cached);
            }
            var node = await FetchNodeFromStruct(nodeStruct, minKeyLength);

            NodeCache?.Add(nodeStruct.OwnPointer, node);
            return(node);
        }
Example #3
0
        private async ValueTask <LTrieNodeExternalLinkStruct> GetRemainingExternalLink(LTrieNodeStruct gn, byte value)
        {
            IMemoryOwner <byte>?owner = null;
            var restLength            = gn.GetRestLength();
            var secondLinkPointer     = gn.GetSecondExternalLinkOwnPointer();

            if (!Storage.TryDirectRead(secondLinkPointer, restLength, out var memory))
            {
                owner = MemoryPool.Rent(restLength);
                var outputMemory = owner.Memory.Slice(0, restLength);
                await Storage.Read(secondLinkPointer, outputMemory);

                memory = outputMemory;
            }
            for (int linkIndex = 0; linkIndex < gn.ExternalLinkSlotCount - 1; linkIndex++)
            {
                var linkOwnPointer = secondLinkPointer + linkIndex * Sizes.ExternalLinkLength;
                var l = new LTrieNodeExternalLinkStruct(linkOwnPointer, memory.Span.Slice(linkIndex * Sizes.ExternalLinkLength, Sizes.ExternalLinkLength));
                if (l.Pointer != 0 && l.Value == value)
                {
                    owner?.Dispose();
                    return(l);
                }
            }
            owner?.Dispose();
            return(default);