Пример #1
0
		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));
		}
Пример #2
0
		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();
			}
		}
Пример #3
0
        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");
        }
Пример #4
0
 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);
 }
Пример #5
0
		private void AssertInReadModeOrCached(BTreeNode node)
		{
			if (IsCached(node))
			{
				return;
			}
			Assert.IsFalse(node.CanWrite());
		}
Пример #6
0
		public virtual void TestTransactionalSize()
		{
			BTreeNode node = Node(3);
			AssertTransactionalSize(node);
			int id = node.GetID();
			BTreeNode readNode = new BTreeNode(id, _btree);
			AssertTransactionalSize(readNode);
		}
Пример #7
0
		public override object Commit(Transaction trans, BTree btree, BTreeNode node)
		{
			if (_transaction == trans)
			{
				return GetObject();
			}
			return this;
		}
Пример #8
0
 private void TellParentAboutChangedKey(Transaction trans)
 {
     if (!IsRoot())
     {
         Db4objects.Db4o.Internal.Btree.BTreeNode parent = _btree.ProduceNode(_parentID);
         parent.KeyChanged(trans, this);
     }
 }
Пример #9
0
 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);
 }
Пример #10
0
		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;
		}
Пример #11
0
 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());
 }
Пример #12
0
        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;
        }
Пример #13
0
 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());
 }
Пример #14
0
        /// <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);
        }
Пример #15
0
 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());
 }
Пример #16
0
 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);
 }
Пример #17
0
        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");
        }
Пример #18
0
		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);
		}
Пример #19
0
        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);
        }
Пример #20
0
 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));
 }
Пример #21
0
		public virtual void NotifySplit(Transaction trans, BTreeNode originalNode, BTreeNode
			 newRightNode)
		{
			if (_structureListener != null)
			{
				_structureListener.NotifySplit(trans, originalNode, newRightNode);
			}
		}
Пример #22
0
		public virtual void NotifyCountChanged(Transaction trans, BTreeNode node, int diff
			)
		{
			if (_structureListener != null)
			{
				_structureListener.NotifyCountChanged(trans, node, diff);
			}
		}
Пример #23
0
		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);
		}
Пример #26
0
		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)
		{
		}
Пример #28
0
		internal virtual void RemoveNode(BTreeNode node)
		{
			_nodes = (TreeIntObject)((TreeInt)_nodes.RemoveLike(new TreeInt(node.GetID())));
		}
Пример #29
0
		public virtual void NotifyDeleted(Transaction trans, BTreeNode node)
		{
			if (_structureListener != null)
			{
				_structureListener.NotifyDeleted(trans, node);
			}
		}
Пример #30
0
			public _IFunction4_605(BTreeNode node)
			{
				this.node = node;
			}
Пример #31
0
		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;
		}
Пример #32
0
		public virtual void SizeChanged(Transaction transaction, BTreeNode node, int changeBy
			)
		{
			NotifyCountChanged(transaction, node, changeBy);
			ByRef sizeInTransaction = SizeIn(transaction);
			sizeInTransaction.value = (((int)sizeInTransaction.value)) + changeBy;
		}
Пример #33
0
 protected abstract void AdjustSizeOnRemovalByOtherTransaction(BTree btree, BTreeNode
     node);
Пример #34
0
		internal virtual void AddNode(BTreeNode node)
		{
			_nodes = (TreeIntObject)((TreeIntObject)Tree.Add(_nodes, new TreeIntObject(node.GetID
				(), node)));
			AddToProcessing(node);
		}
Пример #35
0
		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;
		}
Пример #36
0
		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();
		}
Пример #37
0
 protected override void AdjustSizeOnRemovalByOtherTransaction(BTree btree, BTreeNode
     node)
 {
     // The size was reduced for this entry, let's change back.
     btree.SizeChanged(_transaction, node, +1);
 }
Пример #38
0
		internal virtual void AddToProcessing(BTreeNode node)
		{
			if (_processing != null)
			{
				_processing.Add(node);
			}
		}
Пример #39
0
		public virtual void EvictedFromCache(BTreeNode node)
		{
			_evictedFromCache = ((TreeIntObject)Tree.Add(_evictedFromCache, new TreeIntObject
				(node.GetID(), node)));
		}
Пример #40
0
 public virtual void RemovedBy(Transaction trans, BTree btree, BTreeNode node)
 {
     if (trans != _transaction)
     {
         AdjustSizeOnRemovalByOtherTransaction(btree, node);
     }
     if (HasNext())
     {
         _next.RemovedBy(trans, btree, node);
     }
 }
Пример #41
0
		public BTreeNodeCacheEntry(BTreeNode node)
		{
			_node = node;
		}
Пример #42
0
		public abstract object Commit(Transaction trans, BTree btree, BTreeNode node);