private void AssertTransactionalSize(BTreeNode node) { Transaction otherTrans = NewTransaction(); int originalSize = node.Size(Trans()); Assert.IsGreater(0, originalSize); for (int i = originalSize - 1; i > 0; i--) { object key = node.Key(Trans(), i); node.Remove(Trans(), PrepareComparison(key), key, i); } Assert.AreEqual(1, node.Size(Trans())); Assert.AreEqual(originalSize, node.Size(otherTrans)); node.Commit(Trans()); Assert.AreEqual(1, node.Size(otherTrans)); object newKey = node.Key(Trans(), 0); node.Add(Trans(), PrepareComparison(newKey), newKey); Assert.AreEqual(2, node.Size(Trans())); Assert.AreEqual(1, node.Size(otherTrans)); node.Commit(Trans()); Assert.AreEqual(2, node.Size(Trans())); Assert.AreEqual(2, node.Size(otherTrans)); node.Remove(Trans(), PrepareComparison(newKey), newKey, 1); Assert.AreEqual(1, node.Size(Trans())); Assert.AreEqual(2, node.Size(otherTrans)); node.Add(Trans(), PrepareComparison(newKey), newKey); Assert.AreEqual(2, node.Size(Trans())); Assert.AreEqual(2, node.Size(otherTrans)); }
/// <returns> /// the split node if this node is split /// or this if the first key has changed /// </returns> public Db4objects.Db4o.Internal.Btree.BTreeNode Add(Transaction trans, IPreparedComparison preparedComparison, object obj) { ByteArrayBuffer reader = PrepareRead(trans); Searcher s = Search(trans, preparedComparison, reader); if (_isLeaf) { PrepareWrite(trans); SetStateDirty(); if (WasRemoved(trans, s)) { CancelRemoval(trans, obj, s.Cursor()); return(null); } if (s.Count() > 0 && !s.BeforeFirst()) { s.MoveForward(); } PrepareInsert(s.Cursor()); _keys[s.Cursor()] = ApplyNewAddPatch(trans, obj); } else { Db4objects.Db4o.Internal.Btree.BTreeNode childNode = Child(reader, s.Cursor()); Db4objects.Db4o.Internal.Btree.BTreeNode childNodeOrSplit = childNode.Add(trans, preparedComparison, obj); if (childNodeOrSplit == null) { return(null); } PrepareWrite(trans); SetStateDirty(); _keys[s.Cursor()] = childNode._keys[0]; if (childNode != childNodeOrSplit) { int splitCursor = s.Cursor() + 1; PrepareInsert(splitCursor); _keys[splitCursor] = childNodeOrSplit._keys[0]; _children[splitCursor] = childNodeOrSplit; } } if (MustSplit()) { return(Split(trans)); } if (s.Cursor() == 0) { return(this); } return(null); }