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); }
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); }
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; } } }
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; } } }
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; }
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; }