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)); }
public BTree(Transaction trans, BTreeConfiguration config, int id, IIndexable4 keyHandler , int treeNodeSize) : base(config._idSystem) { _config = config; if (null == keyHandler) { throw new ArgumentNullException(); } _nodeSize = treeNodeSize; _nodeCache = CacheFactory.NewLRUIntCache(config._cacheSize); _halfNodeSize = _nodeSize / 2; _nodeSize = _halfNodeSize * 2; _keyHandler = keyHandler; SetID(id); if (IsNew()) { SetStateDirty(); _root = new BTreeNode(this, 0, true, 0, 0, 0); _root.Write(trans.SystemTransaction()); AddNode(_root); Write(trans.SystemTransaction()); } else { SetStateDeactivated(); } }
private void RemoveChild(Transaction trans, Db4objects.Db4o.Internal.Btree.BTreeNode child) { PrepareWrite(trans); SetStateDirty(); int id = child.GetID(); for (int i = 0; i < _count; i++) { if (ChildID(i) == id) { if (FreeIfEmpty(trans, _count - 1)) { return; } Remove(i); if (i < 1) { TellParentAboutChangedKey(trans); } if (_count == 0) { // root node empty case only, have to turn it into a leaf _isLeaf = true; } return; } } throw new InvalidOperationException("child not found"); }
public void Remove(Transaction trans, IPreparedComparison preparedComparison, object obj, int index) { if (Remove(trans, obj, index)) { return; } // now we try if removal is OK for the next element in this node if (index != LastIndex()) { if (CompareInWriteMode(preparedComparison, index + 1) != 0) { return; } Remove(trans, preparedComparison, obj, index + 1); return; } // nothing else worked so far, move on to the next node, try there Db4objects.Db4o.Internal.Btree.BTreeNode node = NextNode(); if (node == null) { return; } node.PrepareWrite(trans); if (node.CompareInWriteMode(preparedComparison, 0) != 0) { return; } node.Remove(trans, preparedComparison, obj, 0); }
private void AssertInReadModeOrCached(BTreeNode node) { if (IsCached(node)) { return; } Assert.IsFalse(node.CanWrite()); }
public virtual void TestTransactionalSize() { BTreeNode node = Node(3); AssertTransactionalSize(node); int id = node.GetID(); BTreeNode readNode = new BTreeNode(id, _btree); AssertTransactionalSize(readNode); }
public override object Commit(Transaction trans, BTree btree, BTreeNode node) { if (_transaction == trans) { return GetObject(); } return this; }
private void TellParentAboutChangedKey(Transaction trans) { if (!IsRoot()) { Db4objects.Db4o.Internal.Btree.BTreeNode parent = _btree.ProduceNode(_parentID); parent.KeyChanged(trans, this); } }
private Db4objects.Db4o.Internal.Btree.BTreeNode ProduceChild(int index, int childID ) { Db4objects.Db4o.Internal.Btree.BTreeNode child = _btree.ProduceNode(childID); if (_children != null) { _children[index] = child; } return(child); }
public BTreePointer(Transaction transaction, ByteArrayBuffer nodeReader, BTreeNode node, int index) { if (transaction == null || node == null) { throw new ArgumentNullException(); } _transaction = transaction; _nodeReader = nodeReader; _node = node; _index = index; }
public BTreeNode(Transaction trans, BTreeNode firstChild , BTreeNode secondChild) : this(firstChild._btree , 2, false, 0, 0, 0) { _keys[0] = firstChild._keys[0]; _children[0] = firstChild; _keys[1] = secondChild._keys[0]; _children[1] = secondChild; Write(trans.SystemTransaction()); firstChild.SetParentID(trans, GetID()); secondChild.SetParentID(trans, GetID()); }
public override void WriteThis(Transaction trans, ByteArrayBuffer buffer) { int count = 0; int startOffset = buffer._offset; IContext context = trans.Context(); buffer.IncrementOffset(CountLeafAnd3LinkLength); if (_isLeaf) { for (int i = 0; i < _count; i++) { object obj = InternalKey(trans, i); if (obj != No4.Instance) { count++; KeyHandler().WriteIndexEntry(context, buffer, obj); } } } else { for (int i = 0; i < _count; i++) { if (ChildCanSupplyFirstKey(i)) { Db4objects.Db4o.Internal.Btree.BTreeNode child = (Db4objects.Db4o.Internal.Btree.BTreeNode )_children[i]; object childKey = child.FirstKey(trans); if (childKey != No4.Instance) { count++; KeyHandler().WriteIndexEntry(context, buffer, childKey); buffer.WriteIDOf(trans, child); } } else { count++; KeyHandler().WriteIndexEntry(context, buffer, Key(i)); buffer.WriteIDOf(trans, _children[i]); } } } int endOffset = buffer._offset; buffer._offset = startOffset; buffer.WriteInt(count); buffer.WriteByte(_isLeaf ? (byte)1 : (byte)0); buffer.WriteInt(_parentID); buffer.WriteInt(_previousID); buffer.WriteInt(_nextID); buffer._offset = endOffset; }
public BTreeNode(Transaction trans, Db4objects.Db4o.Internal.Btree.BTreeNode firstChild , Db4objects.Db4o.Internal.Btree.BTreeNode secondChild) : this(firstChild._btree , 2, false, 0, 0, 0) { _keys[0] = firstChild._keys[0]; _children[0] = firstChild; _keys[1] = secondChild._keys[0]; _children[1] = secondChild; Write(trans.SystemTransaction()); firstChild.SetParentID(trans, GetID()); secondChild.SetParentID(trans, GetID()); }
/// <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); }
public override bool Equals(object obj) { if (this == obj) { return(true); } if (!(obj is Db4objects.Db4o.Internal.Btree.BTreeNode)) { return(false); } Db4objects.Db4o.Internal.Btree.BTreeNode other = (Db4objects.Db4o.Internal.Btree.BTreeNode )obj; return(GetID() == other.GetID()); }
public override void Free(LocalTransaction trans) { _dead = true; if (!IsRoot()) { Db4objects.Db4o.Internal.Btree.BTreeNode parent = _btree.ProduceNode(_parentID); parent.RemoveChild(trans, this); } PointPreviousTo(trans, _nextID); PointNextTo(trans, _previousID); base.Free((LocalTransaction)trans); _btree.RemoveNode(this); _btree.NotifyDeleted(trans, this); }
private void KeyChanged(Transaction trans, Db4objects.Db4o.Internal.Btree.BTreeNode child) { PrepareWrite(trans); SetStateDirty(); int id = child.GetID(); for (int i = 0; i < _count; i++) { if (ChildID(i) == id) { _keys[i] = child._keys[0]; _children[i] = child; KeyChanged(trans, i); return; } } throw new InvalidOperationException("child not found"); }
public override object Commit(Transaction trans, BTree btree, BTreeNode node) { Db4objects.Db4o.Internal.Btree.BTreeUpdate patch = (Db4objects.Db4o.Internal.Btree.BTreeUpdate )ForTransaction(trans); if (patch is BTreeCancelledRemoval) { object obj = patch.GetCommittedObject(); ApplyKeyChange(obj); } else { if (patch is BTreeRemove) { RemovedBy(trans, btree, node); patch.Committed(btree); return No4.Instance; } } return InternalCommit(trans, btree); }
private Db4objects.Db4o.Internal.Btree.BTreeNode Split(Transaction trans) { Db4objects.Db4o.Internal.Btree.BTreeNode res = new Db4objects.Db4o.Internal.Btree.BTreeNode (_btree, _btree._halfNodeSize, _isLeaf, _parentID, GetID(), _nextID); System.Array.Copy(_keys, _btree._halfNodeSize, res._keys, 0, _btree._halfNodeSize ); for (int i = _btree._halfNodeSize; i < _keys.Length; i++) { _keys[i] = null; } if (_children != null) { res._children = new object[_btree.NodeSize()]; System.Array.Copy(_children, _btree._halfNodeSize, res._children, 0, _btree._halfNodeSize ); for (int i = _btree._halfNodeSize; i < _children.Length; i++) { _children[i] = null; } } _count = _btree._halfNodeSize; res.Write(trans.SystemTransaction()); _btree.AddNode(res); int splitID = res.GetID(); PointNextTo(trans, splitID); SetNextID(trans, splitID); if (_children != null) { for (int i = 0; i < _btree._halfNodeSize; i++) { if (res._children[i] == null) { break; } res.Child(i).SetParentID(trans, splitID); } } _btree.NotifySplit(trans, this, res); return(res); }
private BTreeNodeSearchResult FindLowestLeafMatch(Transaction trans, IPreparedComparison preparedComparison, ByteArrayBuffer reader, int index) { if (index >= 0) { if (!CompareEquals(preparedComparison, trans, reader, index)) { return(null); } if (index > 0) { BTreeNodeSearchResult res = FindLowestLeafMatch(trans, preparedComparison, reader , index - 1); if (res != null) { return(res); } return(CreateMatchingSearchResult(trans, reader, index)); } } Db4objects.Db4o.Internal.Btree.BTreeNode node = PreviousNode(); if (node != null) { ByteArrayBuffer nodeReader = node.PrepareRead(trans); BTreeNodeSearchResult res = node.FindLowestLeafMatch(trans, preparedComparison, nodeReader , node.LastIndex()); if (res != null) { return(res); } } if (index < 0) { return(null); } return(CreateMatchingSearchResult(trans, reader, index)); }
public virtual void NotifySplit(Transaction trans, BTreeNode originalNode, BTreeNode newRightNode) { if (_structureListener != null) { _structureListener.NotifySplit(trans, originalNode, newRightNode); } }
public virtual void NotifyCountChanged(Transaction trans, BTreeNode node, int diff ) { if (_structureListener != null) { _structureListener.NotifyCountChanged(trans, node, diff); } }
public override void ReadThis(Transaction a_trans, ByteArrayBuffer a_reader) { a_reader.IncrementOffset(1); // first byte is version, for possible future format changes _size = a_reader.ReadInt(); _nodeSize = a_reader.ReadInt(); _halfNodeSize = NodeSize() / 2; _root = ProduceNode(a_reader.ReadInt()); }
internal BTreeNodeSearchResult(Transaction trans, ByteArrayBuffer nodeReader, BTree btree, Searcher searcher, BTreeNode node) : this(trans, btree, NextPointerIf(PointerOrNull (trans, nodeReader, node, searcher.Cursor()), searcher.IsGreater()), searcher.FoundMatch ()) { }
private static BTreePointer PointerOrNull(Transaction trans, ByteArrayBuffer nodeReader , BTreeNode node, int cursor) { return node == null ? null : new BTreePointer(trans, nodeReader, node, cursor); }
internal virtual BTreeNodeCacheEntry CacheEntry(BTreeNode node) { return ((BTreeNodeCacheEntry)_nodeCache.Produce(node.GetID(), new _IFunction4_605 (node), new _IProcedure4_609(this))); }
internal BTreeNodeSearchResult(Transaction trans, ByteArrayBuffer nodeReader, BTree btree, BTreeNode node, int cursor, bool foundMatch) : this(trans, btree, PointerOrNull (trans, nodeReader, node, cursor), foundMatch) { }
internal virtual void RemoveNode(BTreeNode node) { _nodes = (TreeIntObject)((TreeInt)_nodes.RemoveLike(new TreeInt(node.GetID()))); }
public virtual void NotifyDeleted(Transaction trans, BTreeNode node) { if (_structureListener != null) { _structureListener.NotifyDeleted(trans, node); } }
public _IFunction4_605(BTreeNode node) { this.node = node; }
private Db4objects.Db4o.Internal.Btree.BTreeNode Split(Transaction trans) { Db4objects.Db4o.Internal.Btree.BTreeNode res = new Db4objects.Db4o.Internal.Btree.BTreeNode (_btree, _btree._halfNodeSize, _isLeaf, _parentID, GetID(), _nextID); System.Array.Copy(_keys, _btree._halfNodeSize, res._keys, 0, _btree._halfNodeSize ); for (int i = _btree._halfNodeSize; i < _keys.Length; i++) { _keys[i] = null; } if (_children != null) { res._children = new object[_btree.NodeSize()]; System.Array.Copy(_children, _btree._halfNodeSize, res._children, 0, _btree._halfNodeSize ); for (int i = _btree._halfNodeSize; i < _children.Length; i++) { _children[i] = null; } } _count = _btree._halfNodeSize; res.Write(trans.SystemTransaction()); _btree.AddNode(res); int splitID = res.GetID(); PointNextTo(trans, splitID); SetNextID(trans, splitID); if (_children != null) { for (int i = 0; i < _btree._halfNodeSize; i++) { if (res._children[i] == null) { break; } res.Child(i).SetParentID(trans, splitID); } } _btree.NotifySplit(trans, this, res); return res; }
public virtual void SizeChanged(Transaction transaction, BTreeNode node, int changeBy ) { NotifyCountChanged(transaction, node, changeBy); ByRef sizeInTransaction = SizeIn(transaction); sizeInTransaction.value = (((int)sizeInTransaction.value)) + changeBy; }
protected abstract void AdjustSizeOnRemovalByOtherTransaction(BTree btree, BTreeNode node);
internal virtual void AddNode(BTreeNode node) { _nodes = (TreeIntObject)((TreeIntObject)Tree.Add(_nodes, new TreeIntObject(node.GetID (), node))); AddToProcessing(node); }
private bool IsCached(BTreeNode node) { for (IEnumerator entryIter = _btree.NodeCache().GetEnumerator(); entryIter.MoveNext (); ) { BTreeNodeCacheEntry entry = ((BTreeNodeCacheEntry)entryIter.Current); if (node == entry._node) { return true; } } return false; }
public virtual void Add(Transaction trans, IPreparedComparison preparedComparison , object key) { EnsureActive(trans); Enlist(trans); BTreeNode rootOrSplit = _root.Add(trans, preparedComparison, key); if (rootOrSplit != null && rootOrSplit != _root) { EnsureDirty(trans); _root = new BTreeNode(trans, _root, rootOrSplit); _root.Write(trans.SystemTransaction()); AddNode(_root); } ConvertCacheEvictedNodesToReadMode(); }
protected override void AdjustSizeOnRemovalByOtherTransaction(BTree btree, BTreeNode node) { // The size was reduced for this entry, let's change back. btree.SizeChanged(_transaction, node, +1); }
internal virtual void AddToProcessing(BTreeNode node) { if (_processing != null) { _processing.Add(node); } }
public virtual void EvictedFromCache(BTreeNode node) { _evictedFromCache = ((TreeIntObject)Tree.Add(_evictedFromCache, new TreeIntObject (node.GetID(), node))); }
public virtual void RemovedBy(Transaction trans, BTree btree, BTreeNode node) { if (trans != _transaction) { AdjustSizeOnRemovalByOtherTransaction(btree, node); } if (HasNext()) { _next.RemovedBy(trans, btree, node); } }
public BTreeNodeCacheEntry(BTreeNode node) { _node = node; }
public abstract object Commit(Transaction trans, BTree btree, BTreeNode node);