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