public BTreePage Split(IFixedLengthKey key, int offset, long pageOffset, float splitFactor) { ProcessDeferredUpdates(); if (splitFactor >= 1 || splitFactor < 0.1) { throw new Exception("BTreePage.Split: splitFactor = " + splitFactor.ToString() + " is not applicable"); } int mIndex = (int)(_maxCount * splitFactor); int off; IFixedLengthKey minKey = MemoryRead(mIndex, out off).FactoryMethod(); BTreePage splittedPage = new BTreePage( new BTreeNode(minKey, off, pageOffset, _maxCount - mIndex), _maxCount, _stream, _factoryKey); CopyBytes(_bytes, mIndex, splittedPage._bytes, 0, _maxCount - mIndex); _treeNode.SetNewCount(mIndex); _rightBound = mIndex; _modified = splittedPage._modified = true; if (key.CompareTo(minKey) < 0) { InsertKey(key, offset); } else { splittedPage.InsertKey(key, offset); } return(splittedPage); }
public override void InsertKey(IFixedLengthKey key, int offset) { _count++; RBNodeBase rbNode; BTreeNode foundNode = SearchBTreeNode(key, offset, out rbNode); if (foundNode == null) { if (_rbTree.Count == 0) { BTreeNode newNode = new BTreeNode(key.FactoryMethod(), offset, GetOffsetForNewPage()); _rbTree.RB_Insert(newNode); BTreePage page = NewPage(newNode); page.InsertKey(key, offset); page.Write(); _cache.CacheObject(newNode.PageOffset, page); return; } else { RBNodeBase rbMinNode = _rbTree.GetMinimumNode(); foundNode = (BTreeNode)rbMinNode.Key; } } else { BTreePage page = PreparePage(foundNode); if (page.Full()) { float splitFactor = (_rbTree.GetNext(rbNode) == null) ? 0.875f : 0.5f; BTreePage splittedPage = page.Split(key, offset, GetOffsetForNewPage(), splitFactor); _rbTree.RB_Insert(splittedPage.BTreeNode); splittedPage.Write(); _cache.CacheObject(splittedPage.BTreeNode.PageOffset, splittedPage); } else { page.InsertKey(key, offset); } } }