Example #1
0
        /// <summary>
        /// split the leaf into two, leave left half in current leaf, and move right half into right node
        /// </summary>
        /// <param name="newKey"></param>
        /// <param name="median">the middle key is popped up</param>
        /// <param name="right"></param>
        public void SplitAtLeaf(IKey newKey, int pos, ref IKey median, ref BNode right)
        {
            Debug.Assert(this.m_leaf);
            Debug.Assert(this.IsFull);

            right.SetOrder(this.m_order);
            right.m_leaf = this.m_leaf;

            int mid = m_order >> 1;

            //copy current keys into a bigger array
            IKey[] temp = new IKey[m_order];
            Array.Copy(m_keys, 0, temp, 0, m_order - 1);
            //insert the newKey into the pos location
            //shift later keys to the right
            for (int i = this.m_keyNums; i > pos; i--)
            {
                temp[i] = temp[i - 1];
            }

            temp[pos] = newKey;

            median = temp[mid];

            //copy left half to current leaf
            for (int i = 0; i < mid; i++)
            {
                m_keys[i] = temp[i];
            }
            //copy right half to right leaf
            for (int i = mid + 1; i < temp.Length; i++)
            {
                right.m_keys[i - mid - 1] = temp[i];
            }

            m_keyNums       = (short)mid;
            right.m_keyNums = (short)(m_order - 1 - mid);

            this.m_dirty  = true;
            right.m_dirty = true;
        }
Example #2
0
		/// <summary>
		/// Create the internal storage for the dbFile.
		/// Note:
		///   1. a helper file for segment managment b-tree is also created if this database file
		///      does not exist.
		/// </summary>
		/// <param name="dbFile"></param>
		public ObjectStore(string dbFileName)
		{
			m_dbFile = new DiskFile(dbFileName);
			m_indexFile = new DiskFile(dbFileName+".idx");
			m_indexPageManager = new memSegmentManager(m_indexFile);

			if (m_indexPageManager.Header.InitializeNeeded)
			{
				m_indexPageManager.Header.NextSegmentId = 0;
				m_indexPageManager.Header.NextObjectId = 0;
				m_indexPageManager.Header.NextClassId = 0;

				//initialize the segment b-tree's top node id
				OOD.Imp.Storage.BNode segTreeTop = new OOD.Imp.Storage.BNode();
				m_indexPageManager.GetNewSegment(segTreeTop);
				segTreeTop.SetOrder(m_segTreeNodeOrder);
				segTreeTop.Leaf = true;
				m_indexPageManager.Header.SegmentTreeTopNodeSId = segTreeTop.SegmentID;

				//initialize the space b-tree's top node id
				BNode spaceTreeTop = new BNode();
				m_indexPageManager.GetNewSegment(spaceTreeTop);
				spaceTreeTop.SetOrder(m_spaceTreeNodeOrder);
				spaceTreeTop.Leaf = true;
				m_indexPageManager.Header.FreeSpaceTreeTopNodeSId = spaceTreeTop.SegmentID;
			}

			m_segmentIndexTree = new SegTree(m_indexPageManager.Header.SegmentTreeTopNodeSId, m_indexPageManager);
			m_spaceIndexTree = new SpaceTree(m_indexPageManager.Header.FreeSpaceTreeTopNodeSId, m_indexPageManager, m_dbFile);

			m_dbSegmentManager = new dbSegmentManager(
				m_indexPageManager.Header.NextSegmentId,
				m_segmentIndexTree,
				m_spaceIndexTree,
				m_dbFile);


			if (m_indexPageManager.Header.InitializeNeeded)
			{
				BNode catalogTop = new BNode();
				m_dbSegmentManager.GetNewSegment(catalogTop);
				catalogTop.SetOrder(m_catalogTreeNodeOrder);
				catalogTop.Leaf = true;

				m_indexPageManager.Header.CatalogTreeTopNodeSId = catalogTop.SegmentID;
			}

			m_catalogTree = new CatalogTree(
				m_indexPageManager.Header.CatalogTreeTopNodeSId,
				m_dbSegmentManager,
				m_indexPageManager.Header.NextClassId);

			m_classCache = new LRUHashtable(m_cache_size, m_classCacheLimit);
			m_objectTreeCache = new LRUHashtable(m_cache_size, m_objectTreeCacheLimit);

			//bring top node's segment tree, space tree, catalog tree into cache, they will be needed anyway
			if (!m_indexPageManager.Header.InitializeNeeded)
			{
				m_indexPageManager.GetSegment(m_segmentIndexTree.TopNodSegId, new BNode(), new KSegId());
				m_indexPageManager.GetSegment(m_spaceIndexTree.TopNodeSId, new BNode(), new KOffset());
				m_dbSegmentManager.GetSegment(m_catalogTree.TopNodeSId, new BNode(), new KCatalog());
			}
		}
Example #3
0
		/* operations regarding class information, scheme */
		public bool InsertClassIno(string className, string[] fieldNames, ref uint assignedCId, ref uint topNodeSId)
		{
			if (m_catalogTree.Search(className) != null)
				return false;
			//reserve a segment id for this class clustering's top node
			BNode classTopSid = new BNode();
			m_dbSegmentManager.GetNewSegment(classTopSid);
			classTopSid.SetOrder(m_classTreeNodeOrder);
			classTopSid.Leaf = true;
			topNodeSId = classTopSid.SegmentID;
			if (m_catalogTree.Insert(className, fieldNames, classTopSid.SegmentID, ref assignedCId) == false)
				throw new OOD.Exception.ProgramLogicError(
					this,
					"Inserting class information failed.");
			return true;
		}
Example #4
0
		/// <summary>
		/// Insert the newKey into this B-tree, 
		/// </summary>
		/// <param name="newKey"></param>
		/// <returns></returns>
		public bool Insert(IKey newKey)
		{
			//find the leaf where the newKey should be in
			BNode n = m_top;
			System.Collections.Stack visited = new System.Collections.Stack();
			int pos = -1;
			while (!n.Leaf)
			{
				IKey temp = n.SearchKey(newKey, ref pos);
				if (temp == null)
				{
					uint nextNodeId = n.GetChildAt(pos);
					visited.Push(n);
					
					n = (BNode)m_sgManager.GetSegment(nextNodeId, m_nodeFactory, m_keyFactory);
				}
				else
					return false;
			}
			
			//now BNode n is the leaf where insert should happen
			IKey t_temp = n.SearchKey(newKey, ref pos);
			if (t_temp == null)
			{
				//not exists, go ahead to insert the new key
				if (!n.IsFull)
				{
					n.InsertAtLeaf(newKey, pos);

					return true;
				}
				else
				{
					//split needed for this node
					BNode right = new BNode();
					m_sgManager.GetNewSegment(right);
					IKey median = null;
					n.SplitAtLeaf(newKey, pos,  ref median, ref right); //this split is at leaf

					bool finished = false;					
					//now n holds the left half of the items, 
					//right holds the right half items, median is the middle key

					while (!finished)
					{			
						//parent is node middle key will be inserted
						BNode parent = (visited.Count >0 ? (BNode)visited.Pop() : null);

						if (parent == null)
						{
							//new top node is needed
							BNode new_top = new BNode();
							m_sgManager.GetNewSegment(new_top);
							new_top.SetOrder(m_top.Order);
							new_top.Leaf = false;
							new_top.InsertFirstKey(median, n.SegmentID, right.SegmentID);

							this.m_top_sid = new_top.SegmentID;

							return true;
						}
						else
						{
							IKey tt = parent.SearchKey(median, ref pos);
							if (tt != null)
								return false;

							if (!parent.IsFull)
							{
								parent.InsertAtInternal(median, pos, right.SegmentID);
								return true;
							}
							else
							{
								//parent is full again
								BNode newRight = new BNode();
								m_sgManager.GetNewSegment(newRight);
								newRight.SetOrder(parent.Order);
								newRight.Leaf = parent.Leaf;
								//this split will insert median into the parent, then split and new middle key is newMedian
								IKey newMedian;
								parent.SplitAtInternal(median, pos, right.SegmentID, out newMedian, newRight);

								n = parent;
								median = newMedian;
								right = newRight;
							}

						}

					}


				}
			}
			else
				return false;

			return false;
		}
Example #5
0
		/// <summary>
		/// split the leaf into two, leave left half in current leaf, and move right half into right node
		/// </summary>
		/// <param name="newKey"></param>
		/// <param name="median">the middle key is popped up</param>
		/// <param name="right"></param>
		public void SplitAtLeaf(IKey newKey, int pos, ref IKey median, ref BNode right)
		{
			Debug.Assert(this.m_leaf);
			Debug.Assert(this.IsFull);

			right.SetOrder(this.m_order);
			right.m_leaf = this.m_leaf;
			
			int mid = m_order >> 1;

			//copy current keys into a bigger array
			IKey[] temp = new IKey[m_order];
			Array.Copy(m_keys,0,temp,0,m_order - 1);
			//insert the newKey into the pos location
			//shift later keys to the right
			for (int i=this.m_keyNums; i>pos; i--)
			{
				temp[i] = temp[i-1];
			}

			temp[pos] = newKey;

			median = temp[mid];

			//copy left half to current leaf
			for (int i=0; i<mid; i++)
			{
				m_keys[i] = temp[i];
			}
			//copy right half to right leaf
			for (int i=mid+1; i<temp.Length; i++)
			{
				right.m_keys[i-mid-1] = temp[i];
			}

			m_keyNums = (short)mid;
			right.m_keyNums = (short)(m_order - 1 - mid);

			this.m_dirty = true;
			right.m_dirty = true;
		}
Example #6
0
        /// <summary>
        /// Create the internal storage for the dbFile.
        /// Note:
        ///   1. a helper file for segment managment b-tree is also created if this database file
        ///      does not exist.
        /// </summary>
        /// <param name="dbFile"></param>
        public ObjectStore(string dbFileName)
        {
            m_dbFile           = new DiskFile(dbFileName);
            m_indexFile        = new DiskFile(dbFileName + ".idx");
            m_indexPageManager = new memSegmentManager(m_indexFile);

            if (m_indexPageManager.Header.InitializeNeeded)
            {
                m_indexPageManager.Header.NextSegmentId = 0;
                m_indexPageManager.Header.NextObjectId  = 0;
                m_indexPageManager.Header.NextClassId   = 0;

                //initialize the segment b-tree's top node id
                OOD.Imp.Storage.BNode segTreeTop = new OOD.Imp.Storage.BNode();
                m_indexPageManager.GetNewSegment(segTreeTop);
                segTreeTop.SetOrder(m_segTreeNodeOrder);
                segTreeTop.Leaf = true;
                m_indexPageManager.Header.SegmentTreeTopNodeSId = segTreeTop.SegmentID;

                //initialize the space b-tree's top node id
                BNode spaceTreeTop = new BNode();
                m_indexPageManager.GetNewSegment(spaceTreeTop);
                spaceTreeTop.SetOrder(m_spaceTreeNodeOrder);
                spaceTreeTop.Leaf = true;
                m_indexPageManager.Header.FreeSpaceTreeTopNodeSId = spaceTreeTop.SegmentID;
            }

            m_segmentIndexTree = new SegTree(m_indexPageManager.Header.SegmentTreeTopNodeSId, m_indexPageManager);
            m_spaceIndexTree   = new SpaceTree(m_indexPageManager.Header.FreeSpaceTreeTopNodeSId, m_indexPageManager, m_dbFile);

            m_dbSegmentManager = new dbSegmentManager(
                m_indexPageManager.Header.NextSegmentId,
                m_segmentIndexTree,
                m_spaceIndexTree,
                m_dbFile);


            if (m_indexPageManager.Header.InitializeNeeded)
            {
                BNode catalogTop = new BNode();
                m_dbSegmentManager.GetNewSegment(catalogTop);
                catalogTop.SetOrder(m_catalogTreeNodeOrder);
                catalogTop.Leaf = true;

                m_indexPageManager.Header.CatalogTreeTopNodeSId = catalogTop.SegmentID;
            }

            m_catalogTree = new CatalogTree(
                m_indexPageManager.Header.CatalogTreeTopNodeSId,
                m_dbSegmentManager,
                m_indexPageManager.Header.NextClassId);

            m_classCache      = new LRUHashtable(m_cache_size, m_classCacheLimit);
            m_objectTreeCache = new LRUHashtable(m_cache_size, m_objectTreeCacheLimit);

            //bring top node's segment tree, space tree, catalog tree into cache, they will be needed anyway
            if (!m_indexPageManager.Header.InitializeNeeded)
            {
                m_indexPageManager.GetSegment(m_segmentIndexTree.TopNodSegId, new BNode(), new KSegId());
                m_indexPageManager.GetSegment(m_spaceIndexTree.TopNodeSId, new BNode(), new KOffset());
                m_dbSegmentManager.GetSegment(m_catalogTree.TopNodeSId, new BNode(), new KCatalog());
            }
        }
Example #7
0
        /// <summary>
        /// Insert the newKey into this B-tree,
        /// </summary>
        /// <param name="newKey"></param>
        /// <returns></returns>
        public bool Insert(IKey newKey)
        {
            //find the leaf where the newKey should be in
            BNode n = m_top;

            System.Collections.Stack visited = new System.Collections.Stack();
            int pos = -1;

            while (!n.Leaf)
            {
                IKey temp = n.SearchKey(newKey, ref pos);
                if (temp == null)
                {
                    uint nextNodeId = n.GetChildAt(pos);
                    visited.Push(n);

                    n = (BNode)m_sgManager.GetSegment(nextNodeId, m_nodeFactory, m_keyFactory);
                }
                else
                {
                    return(false);
                }
            }

            //now BNode n is the leaf where insert should happen
            IKey t_temp = n.SearchKey(newKey, ref pos);

            if (t_temp == null)
            {
                //not exists, go ahead to insert the new key
                if (!n.IsFull)
                {
                    n.InsertAtLeaf(newKey, pos);

                    return(true);
                }
                else
                {
                    //split needed for this node
                    BNode right = new BNode();
                    m_sgManager.GetNewSegment(right);
                    IKey median = null;
                    n.SplitAtLeaf(newKey, pos, ref median, ref right);                      //this split is at leaf

                    bool finished = false;
                    //now n holds the left half of the items,
                    //right holds the right half items, median is the middle key

                    while (!finished)
                    {
                        //parent is node middle key will be inserted
                        BNode parent = (visited.Count > 0 ? (BNode)visited.Pop() : null);

                        if (parent == null)
                        {
                            //new top node is needed
                            BNode new_top = new BNode();
                            m_sgManager.GetNewSegment(new_top);
                            new_top.SetOrder(m_top.Order);
                            new_top.Leaf = false;
                            new_top.InsertFirstKey(median, n.SegmentID, right.SegmentID);

                            this.m_top_sid = new_top.SegmentID;

                            return(true);
                        }
                        else
                        {
                            IKey tt = parent.SearchKey(median, ref pos);
                            if (tt != null)
                            {
                                return(false);
                            }

                            if (!parent.IsFull)
                            {
                                parent.InsertAtInternal(median, pos, right.SegmentID);
                                return(true);
                            }
                            else
                            {
                                //parent is full again
                                BNode newRight = new BNode();
                                m_sgManager.GetNewSegment(newRight);
                                newRight.SetOrder(parent.Order);
                                newRight.Leaf = parent.Leaf;
                                //this split will insert median into the parent, then split and new middle key is newMedian
                                IKey newMedian;
                                parent.SplitAtInternal(median, pos, right.SegmentID, out newMedian, newRight);

                                n      = parent;
                                median = newMedian;
                                right  = newRight;
                            }
                        }
                    }
                }
            }
            else
            {
                return(false);
            }

            return(false);
        }