예제 #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);
        }
예제 #2
0
        public PrefixNode[] GetPrefixes()
        {
            var prefixes = new PrefixNode[_prefixSection->NextPrefixId];

            for (byte prefixId = 0; prefixId < _prefixSection->NextPrefixId; prefixId++)
            {
                var prefix = new PrefixNode();
                prefix.Set(_base + _prefixSection->PrefixOffsets[prefixId], PageNumber);
                prefixes[prefixId] = prefix;
            }

            return(prefixes);
        }
예제 #3
0
        private void Defrag(Transaction tx)
        {
            TemporaryPage tmp;

            using (tx.Environment.GetTemporaryPage(tx, out tmp))
            {
                var tempPage = tmp.GetTempPage(KeysPrefixed);
                MemoryUtils.Copy(tempPage.Base, Base, _pageSize);

                var numberOfEntries = NumberOfEntries;

                Upper = KeysPrefixed ? (ushort)(_pageSize - Constants.PrefixInfoSectionSize) : _pageSize;

                for (int i = 0; i < numberOfEntries; i++)
                {
                    var node = tempPage.GetNode(i);
                    var size = node->GetNodeSize() - Constants.NodeOffsetSize;
                    size += size & 1;
                    MemoryUtils.Copy(Base + Upper - size, (byte *)node, size);
                    Upper         -= (ushort)size;
                    KeysOffsets[i] = Upper;
                }

                if (KeysPrefixed == false)
                {
                    return;
                }

                var prefixNode = new PrefixNode();

                for (byte i = 0; i < _prefixSection->NextPrefixId; i++)
                {
                    tempPage.AssertPrefixNode(i);

                    prefixNode.Set(tempPage._base + tempPage._prefixSection->PrefixOffsets[i], tempPage.PageNumber);

                    var prefixNodeSize = Constants.PrefixNodeHeaderSize + prefixNode.PrefixLength;
                    prefixNodeSize += prefixNodeSize & 1;

                    MemoryUtils.Copy(Base + Upper - prefixNodeSize, prefixNode.Base, prefixNodeSize);
                    Upper -= (ushort)prefixNodeSize;
                    _prefixSection->PrefixOffsets[i] = Upper;
                }
            }
        }
예제 #4
0
        private void Defrag(Transaction tx)
        {
            TemporaryPage tmp;
            using (tx.Environment.GetTemporaryPage(tx, out tmp))
            {
                var tempPage = tmp.GetTempPage(KeysPrefixed);
                Memory.Copy(tempPage.Base, Base, _pageSize);

                var numberOfEntries = NumberOfEntries;

                Upper = KeysPrefixed ? (ushort) (_pageSize - Constants.PrefixInfoSectionSize) : _pageSize;

                for (int i = 0; i < numberOfEntries; i++)
                {
                    var node = tempPage.GetNode(i);
                    var size = node->GetNodeSize() - Constants.NodeOffsetSize;
                    size += size & 1;
                    Memory.Copy(Base + Upper - size, (byte*)node, size);
                    Upper -= (ushort) size;
                    KeysOffsets[i] = Upper;
                }

                if (KeysPrefixed == false)
                    return;
                
                var prefixNode = new PrefixNode();

                for (byte i = 0; i < _prefixSection->NextPrefixId; i++)
                {
                    tempPage.AssertPrefixNode(i);

                    prefixNode.Set(tempPage._base + tempPage._prefixSection->PrefixOffsets[i], tempPage.PageNumber);

                    var prefixNodeSize = Constants.PrefixNodeHeaderSize + prefixNode.PrefixLength;
                    prefixNodeSize += prefixNodeSize & 1;

                    Memory.Copy(Base + Upper - prefixNodeSize, prefixNode.Base, prefixNodeSize);
                    Upper -= (ushort) prefixNodeSize;
                    _prefixSection->PrefixOffsets[i] = Upper;
                }
            }
        }
예제 #5
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;
        }
예제 #6
0
        public PrefixNode[] GetPrefixes()
        {
            var prefixes = new PrefixNode[_prefixSection->NextPrefixId];

            for (byte prefixId = 0; prefixId < _prefixSection->NextPrefixId; prefixId++)
            {
                var prefix = new PrefixNode();
                prefix.Set(_base + _prefixSection->PrefixOffsets[prefixId], PageNumber);
                prefixes[prefixId] = prefix;
            }

            return prefixes;
        }