Beispiel #1
0
        private bool TryUseExistingPrefix(MemorySlice key, out PrefixedSlice prefixedSlice)
        {
            if (_prefixSection->NextPrefixId < 1)
            {
                prefixedSlice = null;
                return(false);
            }

            var prefix = new PrefixNode();

            BestPrefixMatch bestMatch = null;

            for (byte prefixId = 0; prefixId < _prefixSection->NextPrefixId; prefixId++)
            {
                AssertPrefixNode(prefixId);

                prefix.Set(_base + _prefixSection->PrefixOffsets[prefixId], PageNumber);

                var length = key.FindPrefixSize(new Slice(prefix.ValuePtr, prefix.PrefixLength));
                if (length == 0)
                {
                    continue;
                }

                if (length == prefix.PrefixLength)                 // full prefix usage
                {
                    prefixedSlice = new PrefixedSlice(prefixId, length, key.Skip(length));
                    return(true);
                }

                // keep on looking for a better prefix

                if (bestMatch == null)
                {
                    bestMatch = new BestPrefixMatch
                    {
                        PrefixId    = prefixId,
                        PrefixUsage = length
                    };
                }
                else if (length > bestMatch.PrefixUsage)
                {
                    bestMatch.PrefixId    = prefixId;
                    bestMatch.PrefixUsage = length;
                }
            }

            if (bestMatch != null && bestMatch.PrefixUsage > MinPrefixLength(key))
            {
                prefixedSlice = new PrefixedSlice(bestMatch.PrefixId, bestMatch.PrefixUsage, key.Skip(bestMatch.PrefixUsage));
                return(true);
            }

            prefixedSlice = null;
            return(false);
        }
Beispiel #2
0
        private bool TryCreateNewPrefix(MemorySlice key, int nodeIndex, out PrefixedSlice prefixedSlice)
        {
            if (_prefixSection->NextPrefixId >= PrefixCount || NumberOfEntries == 0)
            {
                prefixedSlice = null;
                return false;
            }

            MemorySlice left;
            MemorySlice right;

            if (nodeIndex > 0 && nodeIndex < NumberOfEntries) // middle
            {
                left = GetNodeKey(nodeIndex - 1);
                right = GetNodeKey(nodeIndex);
            }
            else if (nodeIndex == 0) // first
            {
                left = null;
                right = GetNodeKey(0);
            }
            else if (nodeIndex == NumberOfEntries) // last
            {
                left = GetNodeKey(nodeIndex - 1);
                right = null;
            }
            else
                throw new NotSupportedException("Invalid node index prefix: " + nodeIndex + ". Number of entries: " + NumberOfEntries);

            ushort leftLength = 0;
            ushort rightLength = 0;

            if (left != null && left.Size > 0) // not before all keys
                leftLength = key.FindPrefixSize(left);

            if (right != null)
                rightLength = key.FindPrefixSize(right);

            var minPrefixLength = MinPrefixLength(key);

            if (left != null && leftLength > minPrefixLength && leftLength > rightLength)
            {
                prefixedSlice = new PrefixedSlice(_prefixSection->NextPrefixId, leftLength, key.Skip(leftLength))
                {
                    NewPrefix = new Slice(left.ToSlice(), leftLength)
                };

                return true;
            }

            if (right != null && rightLength > minPrefixLength && rightLength > leftLength)
            {
                prefixedSlice = new PrefixedSlice(_prefixSection->NextPrefixId, rightLength, key.Skip(rightLength))
                {
                    NewPrefix = new Slice(right.ToSlice(), rightLength)
                };

                return true;
            }

            prefixedSlice = null;
            return false;
        }
Beispiel #3
0
        private bool TryUseExistingPrefix(MemorySlice key, out PrefixedSlice prefixedSlice)
        {
            if (_prefixSection->NextPrefixId < 1)
            {
                prefixedSlice = null;
                return false;
            }

            BestPrefixMatch bestMatch = null;

            for (byte prefixId = 0; prefixId < _prefixSection->NextPrefixId; prefixId++)
            {
                AssertPrefixNode(prefixId);

                var prefix = new PrefixNode();

                prefix.Set(_base + _prefixSection->PrefixOffsets[prefixId], PageNumber);

                var length = key.FindPrefixSize(new Slice(prefix.ValuePtr, prefix.PrefixLength));
                if (length == 0)
                    continue;

                if (length == prefix.PrefixLength) // full prefix usage
                {
                    prefixedSlice = new PrefixedSlice(prefixId, length, key.Skip(length))
                    {
                        Prefix = prefix
                    };
                    return true;
                }

                // keep on looking for a better prefix

                if (bestMatch == null)
                {
                    bestMatch = new BestPrefixMatch
                    {
                        PrefixId = prefixId,
                        PrefixUsage = length,
                        PrefixNode = prefix
                    };
                }
                else if (length > bestMatch.PrefixUsage)
                {
                    bestMatch.PrefixId = prefixId;
                    bestMatch.PrefixUsage = length;
                    bestMatch.PrefixNode = prefix;
                }
            }

            if (bestMatch != null && bestMatch.PrefixUsage > MinPrefixLength(key))
            {
                prefixedSlice = new PrefixedSlice(bestMatch.PrefixId, bestMatch.PrefixUsage, key.Skip(bestMatch.PrefixUsage))
                {
                    Prefix = bestMatch.PrefixNode
                };
                return true;
            }

            prefixedSlice = null;
            return false;
        }
Beispiel #4
0
        private bool TryCreateNewPrefix(MemorySlice key, int nodeIndex, out PrefixedSlice prefixedSlice)
        {
            if (_prefixSection->NextPrefixId >= PrefixCount || NumberOfEntries == 0)
            {
                prefixedSlice = null;
                return(false);
            }

            MemorySlice left;
            MemorySlice right;

            if (nodeIndex > 0 && nodeIndex < NumberOfEntries)             // middle
            {
                left  = GetNodeKey(nodeIndex - 1);
                right = GetNodeKey(nodeIndex);
            }
            else if (nodeIndex == 0)             // first
            {
                left  = null;
                right = GetNodeKey(0);
            }
            else if (nodeIndex == NumberOfEntries)             // last
            {
                left  = GetNodeKey(nodeIndex - 1);
                right = null;
            }
            else
            {
                throw new NotSupportedException("Invalid node index prefix: " + nodeIndex + ". Number of entries: " + NumberOfEntries);
            }

            ushort leftLength  = 0;
            ushort rightLength = 0;

            if (left != null && left.Size > 0)             // not before all keys
            {
                leftLength = key.FindPrefixSize(left);
            }

            if (right != null)
            {
                rightLength = key.FindPrefixSize(right);
            }

            var minPrefixLength = MinPrefixLength(key);

            if (left != null && leftLength > minPrefixLength && leftLength > rightLength)
            {
                prefixedSlice = new PrefixedSlice(_prefixSection->NextPrefixId, leftLength, key.Skip(leftLength))
                {
                    NewPrefix = new Slice(left.ToSlice(), leftLength)
                };

                return(true);
            }

            if (right != null && rightLength > minPrefixLength && rightLength > leftLength)
            {
                prefixedSlice = new PrefixedSlice(_prefixSection->NextPrefixId, rightLength, key.Skip(rightLength))
                {
                    NewPrefix = new Slice(right.ToSlice(), rightLength)
                };

                return(true);
            }

            prefixedSlice = null;
            return(false);
        }