public void InsertRecord(DataRecord dataRecord) { var record = FindByKey(dataRecord.Key); if (record != null) { throw new KeyAlreadyExistsException(); } var dataPointer = DataFreeSpaceMap.AllocatePage(); DataIO.WriteRecord(dataRecord.Record, dataPointer); var nodeRecord = new NodeRecord(dataRecord.Key, dataPointer); try { _currentPage.InsertRecord(nodeRecord); } catch (PageOverflowException) { //kompensacja lub rozszczepienie if (!Compensate()) { Split(); } return; } BtreeIO.WritePage(_currentPage.GetBTreePage(), _currentPage.SelfIndex); }
private void Split() { if (_currentPage.SelfIndex == BTreeHeaderPage.RootIndex) //root split { SplitRoot(); return; } var pathPart = _path.Pop(); var parentPage = pathPart.ParentPage; var childrenIndex = pathPart.ChildrenIndex; var newPage = new BTreePage(parentPage.SelfIndex, BTreeFreeSpaceMap.AllocatePage()); if (!_currentPage.IsLeaf) { newPage.IsLeaf = false; } parentPage.Childrens.Insert(childrenIndex, newPage.SelfIndex); var recordsPerPage = _currentPage.GetPresentRecords() / 2; for (var i = 0; i < recordsPerPage; i++) { newPage.InsertRecord(_currentPage.PopRecordAt(0, false)); } if (!_currentPage.IsLeaf) { for (var i = 0; i < recordsPerPage + 1; i++) { newPage.Childrens.Add(_currentPage.PopChildrenAt(0)); } } var forParent = _currentPage.PopRecordAt(0, false); BtreeIO.WritePage(_currentPage.GetBTreePage(), _currentPage.SelfIndex); BtreeIO.WritePage(newPage.GetBTreePage(), newPage.SelfIndex); try { parentPage.InsertRecord(forParent); BtreeIO.WritePage(parentPage.GetBTreePage(), parentPage.SelfIndex); } catch (PageOverflowException) { _currentPage = parentPage; if (Compensate()) { return; } Split(); } }
public void Dispose() { BtreeIO.WritePage(RootPage.GetBTreePage(), RootPage.SelfIndex); BtreeIO.WritePage(BTreeHeader.GetHeaderPage(), 0); BTreeFreeSpaceMap.Dispose(); DataFreeSpaceMap.Dispose(); BtreeIO.Stream.Dispose(); DataIO.Stream.Dispose(); }
private void SplitRoot() { var rootPage = new BTreePage(0, BTreeFreeSpaceMap.AllocatePage()); rootPage.IsLeaf = false; _currentPage.ParentIndex = rootPage.SelfIndex; var newPage = new BTreePage(rootPage.SelfIndex, BTreeFreeSpaceMap.AllocatePage()); if (!_currentPage.IsLeaf) { newPage.IsLeaf = false; } rootPage.Childrens.Add(newPage.SelfIndex); rootPage.Childrens.Add(_currentPage.SelfIndex); var recordsPerPage = _currentPage.GetPresentRecords() / 2; for (var i = 0; i < recordsPerPage; i++) { newPage.InsertRecord(_currentPage.PopRecordAt(0, false)); } if (!_currentPage.IsLeaf) { for (var i = 0; i < recordsPerPage + 1; i++) { newPage.Childrens.Add(_currentPage.PopChildrenAt(0)); } } rootPage.InsertRecord(_currentPage.PopRecordAt(0, false)); BtreeIO.WritePage(_currentPage.GetBTreePage(), _currentPage.SelfIndex); BtreeIO.WritePage(newPage.GetBTreePage(), newPage.SelfIndex); BtreeIO.WritePage(rootPage.GetBTreePage(), rootPage.SelfIndex); RootPage = rootPage; BTreeHeaderPage.RootIndex = RootPage.SelfIndex; }
private void Merge() { var partPath = _path.Pop(); var parentPage = partPath.ParentPage; var childrenIndex = partPath.ChildrenIndex; BTreePage leftBrother = null, rightBrother = null; if (childrenIndex == 0) //zrobic zapisy { rightBrother = new BTreePage(BtreeIO.ReadPage(parentPage.Childrens[childrenIndex + 1])); var recordsToTransfer = rightBrother.GetPresentRecords(); for (var i = 0; i < recordsToTransfer; i++) { _currentPage.InsertRecord(rightBrother.PopRecordAt(0, true)); } if (!_currentPage.IsLeaf) { for (var i = 0; i < recordsToTransfer + 1; i++) { _currentPage.Childrens.Add(rightBrother.PopChildrenAt(0)); } } parentPage.PopChildrenAt(childrenIndex + 1); _currentPage.InsertRecord(parentPage.Records[childrenIndex]); BTreeFreeSpaceMap.FreePage(rightBrother.SelfIndex); BtreeIO.WritePage(_currentPage.GetBTreePage(), _currentPage.SelfIndex); } else { leftBrother = new BTreePage(BtreeIO.ReadPage(parentPage.Childrens[childrenIndex - 1])); var recordsToTransfer = _currentPage.GetPresentRecords(); for (var i = 0; i < recordsToTransfer; i++) { leftBrother.InsertRecord(_currentPage.PopRecordAt(0, true)); } if (!_currentPage.IsLeaf) { for (var i = 0; i < recordsToTransfer + 1; i++) { leftBrother.Childrens.Add(_currentPage.PopChildrenAt(0)); } } parentPage.PopChildrenAt(childrenIndex); leftBrother.InsertRecord(parentPage.Records[childrenIndex - 1]); BTreeFreeSpaceMap.FreePage(_currentPage.SelfIndex); BtreeIO.WritePage(leftBrother.GetBTreePage(), leftBrother.SelfIndex); } try { if (childrenIndex == 0) { parentPage.PopRecordAt(childrenIndex, false); } else { parentPage.PopRecordAt(childrenIndex - 1, false); } BtreeIO.WritePage(parentPage.GetBTreePage(), parentPage.SelfIndex); } catch (PageDeficitException ex) { _currentPage = parentPage; if (!Compensate()) { Merge(); } } catch (RootPageDeficitException ex) { BTreeFreeSpaceMap.FreePage(RootPage.SelfIndex); if (childrenIndex == 0) { RootPage = _currentPage; BTreeHeaderPage.RootIndex = _currentPage.SelfIndex; } else { RootPage = leftBrother; BTreeHeaderPage.RootIndex = leftBrother.SelfIndex; } } }