public void RemoveEntry(byte[] key) { if (!m_rootRecord.IsParentNode) { int index = CollationHelper.FindIndexInLeafNode(m_rootRecord.IndexEntries, key, m_rootRecord.CollationRule); if (index >= 0) { m_rootRecord.IndexEntries.RemoveAt(index); } m_volume.UpdateFileRecord(m_fileRecord); } else { int indexOfEntryToRemove; KeyValuePairList <int, IndexRecord> path = FindRemovalPath(key, out indexOfEntryToRemove); if (path == null) { return; } if ((path.Count > 0 && path[path.Count - 1].Value.IsParentNode) || path.Count == 0) { // We find the rightmost leaf entry in the left branch and put it instead. // Note: Excluding the root of the branch, the rightmost leaf entry in the branch collates last. KeyValuePairList <int, IndexRecord> pathToLeaf = FindPathToRightmostLeaf(path, indexOfEntryToRemove); IndexRecord leaf = pathToLeaf[pathToLeaf.Count - 1].Value; IndexEntry entryToRemoveFromLeaf = leaf.IndexEntries[leaf.IndexEntries.Count - 1]; leaf.IndexEntries.RemoveAt(leaf.IndexEntries.Count - 1); long leafRecordIndex = ConvertToRecordIndex(leaf.RecordVBN); // Note: CHKDSK does not accept an empty IndexRecord, however, we must not call RemovePointer just yet because it might affect the parent as well. WriteIndexRecord(leafRecordIndex, leaf); if (path.Count == 0) { m_rootRecord.IndexEntries[indexOfEntryToRemove].FileReference = entryToRemoveFromLeaf.FileReference; m_rootRecord.IndexEntries[indexOfEntryToRemove].Key = entryToRemoveFromLeaf.Key; m_volume.UpdateFileRecord(m_fileRecord); } else { path[path.Count - 1].Value.IndexEntries[indexOfEntryToRemove].FileReference = entryToRemoveFromLeaf.FileReference; path[path.Count - 1].Value.IndexEntries[indexOfEntryToRemove].Key = entryToRemoveFromLeaf.Key; long recordIndex = ConvertToRecordIndex(path[path.Count - 1].Value.RecordVBN); WriteIndexRecord(recordIndex, path[path.Count - 1].Value); } if (leaf.IndexEntries.Count == 0) { int indexOfLeafPointer = pathToLeaf[pathToLeaf.Count - 1].Key; RemovePointer(pathToLeaf.GetRange(0, pathToLeaf.Count - 1), indexOfLeafPointer); DeallocateIndexRecord(leafRecordIndex); } } else { int indexInParentRecord = path[path.Count - 1].Key; IndexRecord leaf = path[path.Count - 1].Value; leaf.IndexEntries.RemoveAt(indexOfEntryToRemove); long recordIndex = ConvertToRecordIndex(leaf.RecordVBN); if (leaf.IndexEntries.Count > 0) { WriteIndexRecord(recordIndex, leaf); } else { path.RemoveAt(path.Count - 1); RemovePointer(path, indexInParentRecord); DeallocateIndexRecord(recordIndex); } } } }