⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bplustreelong.java

📁 R树与B树的混合树
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
					{
						this.smallestKey = key; // deleted value
					}
				}
				return this.smallestKey;
			}
		}
		String LeastKey() 
			throws Exception
		{
			String result = null;
			if (this.isLeaf) 
			{
				result = this.ChildKeys[0];
			} 
			else 
			{
				this.MaterializeNodeAtIndex(0);
				result = this.MaterializedChildNodes[0].LeastKey();
			}
			if (result==null) 
			{
				throw new BplusTreeException("no key found");
			}
			return result;
		}
		public static String Merge(BplusNode left, String KeyBetween, BplusNode right) //, out String rightLeastKey, 
			//out boolean DeleteRight) 
			throws Exception
		{
			//System.Diagnostics.Debug.WriteLine("\r\n<br> merging "+right.myBufferNumber+" ("+KeyBetween+") "+left.myBufferNumber);
			//System.Diagnostics.Debug.WriteLine(left.owner.toHtml());
			//rightLeastKey = null; // only if DeleteRight
			if (left.isLeaf || right.isLeaf) 
			{
				if (!(left.isLeaf&&right.isLeaf)) 
				{
					throw new BplusTreeException("can't merge leaf with non-leaf");
				}
				MergeLeaves(left, right); //, out DeleteRight);
				String rightLeastKey = right.ChildKeys[0];
				return rightLeastKey;
			}
			// merge non-leaves
			//DeleteRight = false;
			String[] allkeys = new String[left.Size*2+1];
			long[] allseeks = new long[left.Size*2+2];
			BplusNode[] allMaterialized = new BplusNode[left.Size*2+2];
			if (left.ChildBufferNumbers[0]==BplusTreeLong.NULLBUFFERNUMBER ||
				right.ChildBufferNumbers[0]==BplusTreeLong.NULLBUFFERNUMBER) 
			{
				throw new BplusTreeException("cannot merge empty non-leaf with non-leaf");
			}
			int index = 0;
			allseeks[0] = left.ChildBufferNumbers[0];
			allMaterialized[0] = left.MaterializedChildNodes[0];
			for (int i=0; i<left.Size; i++) 
			{
				if (left.ChildKeys[i]==null) 
				{
					break;
				}
				allkeys[index] = left.ChildKeys[i];
				allseeks[index+1] = left.ChildBufferNumbers[i+1];
				allMaterialized[index+1] = left.MaterializedChildNodes[i+1];
				index++;
			}
			allkeys[index] = KeyBetween;
			index++;
			allseeks[index] = right.ChildBufferNumbers[0];
			allMaterialized[index] = right.MaterializedChildNodes[0];
			int rightcount = 0;
			for (int i=0; i<right.Size; i++) 
			{
				if (right.ChildKeys[i]==null) 
				{
					break;
				}
				allkeys[index] = right.ChildKeys[i];
				allseeks[index+1] = right.ChildBufferNumbers[i+1];
				allMaterialized[index+1] = right.MaterializedChildNodes[i+1];
				index++;
				rightcount++;
			}
			if (index<=left.Size) 
			{
				// it will all fit in one node
				//System.Diagnostics.Debug.WriteLine("deciding to forget "+right.myBufferNumber+" into "+left.myBufferNumber);
				//DeleteRight = true;
				right.isValid = false;
				for (int i=0; i<index; i++) 
				{
					left.ChildKeys[i] = allkeys[i];
					left.ChildBufferNumbers[i] = allseeks[i];
					left.MaterializedChildNodes[i] = allMaterialized[i];
				}
				left.ChildBufferNumbers[index] = allseeks[index];
				left.MaterializedChildNodes[index] = allMaterialized[index];
				left.reParentAllChildren();
				left.Soil();
				right.Free();
				return null;
			}
			// otherwise split the content between the nodes
			left.Clear();
			right.Clear();
			left.Soil();
			right.Soil();
			int leftcontent = index/2;
			int rightcontent = index-leftcontent-1;
			String rightLeastKey = allkeys[leftcontent];
			int outputindex = 0;
			for (int i=0; i<leftcontent; i++) 
			{
				left.ChildKeys[i] = allkeys[outputindex];
				left.ChildBufferNumbers[i] = allseeks[outputindex];
				left.MaterializedChildNodes[i] = allMaterialized[outputindex];
				outputindex++;
			}
			rightLeastKey = allkeys[outputindex];
			left.ChildBufferNumbers[outputindex] = allseeks[outputindex];
			left.MaterializedChildNodes[outputindex] = allMaterialized[outputindex];
			outputindex++;
			rightcount = 0;
			for (int i=0; i<rightcontent; i++) 
			{
				right.ChildKeys[i] = allkeys[outputindex];
				right.ChildBufferNumbers[i] = allseeks[outputindex];
				right.MaterializedChildNodes[i] = allMaterialized[outputindex];
				outputindex++;
				rightcount++;
			}
			right.ChildBufferNumbers[rightcount] = allseeks[outputindex];
			right.MaterializedChildNodes[rightcount] = allMaterialized[outputindex];
			left.reParentAllChildren();
			right.reParentAllChildren();
			return rightLeastKey;
		}
		public static void MergeLeaves(BplusNode left, BplusNode right) //, out boolean DeleteRight) 
			throws Exception
		{
			//DeleteRight = false;
			String[] allkeys = new String[left.Size*2];
			long[] allseeks = new long[left.Size*2];
			int index = 0;
			for (int i=0; i<left.Size; i++) 
			{
				if (left.ChildKeys[i]==null) 
				{
					break;
				}
				allkeys[index] = left.ChildKeys[i];
				allseeks[index] = left.ChildBufferNumbers[i];
				index++;
			}
			for (int i=0; i<right.Size; i++) 
			{
				if (right.ChildKeys[i]==null) 
				{
					break;
				}
				allkeys[index] = right.ChildKeys[i];
				allseeks[index] = right.ChildBufferNumbers[i];
				index++;
			}
			if (index<=left.Size) 
			{
				left.Clear();
				//DeleteRight = true;
				right.isValid = false;
				for (int i=0; i<index; i++) 
				{
					left.ChildKeys[i] = allkeys[i];
					left.ChildBufferNumbers[i] = allseeks[i];
				}
				right.Free();
				left.Soil();
				return;
			}
			left.Clear();
			right.Clear();
			left.Soil();
			right.Soil();
			int rightcontent = index/2;
			int leftcontent = index - rightcontent;
			int newindex = 0;
			for (int i=0; i<leftcontent; i++) 
			{
				left.ChildKeys[i] = allkeys[newindex];
				left.ChildBufferNumbers[i] = allseeks[newindex];
				newindex++;
			}
			for (int i=0; i<rightcontent; i++) 
			{
				right.ChildKeys[i] = allkeys[newindex];
				right.ChildBufferNumbers[i] = allseeks[newindex];
				newindex++;
			}
		}
		//		public String DeleteLeaf(String key, out boolean MergeMe) 
		//		{
		//			String result = null;
		//			MergeMe = false;
		//			boolean found = false;
		//			int deletelocation = 0;
		//			foreach (String thiskey in this.ChildKeys) 
		//													 {
		//														 // use comparison, not equals, in case different Strings sometimes compare same
		//														 if (thiskey!=null && this.owner.Compare(thiskey, key)==0) // thiskey.equals(key)
		//														 {
		//															 found = true;
		//															 break;
		//														 }
		//														 deletelocation++;
		//													 }
		//			if (!found) 
		//			{
		//				throw new BplusTreeKeyMissing("cannot delete missing key: "+key);
		//			}
		//			this.Soil();
		//			// only keys are important...
		//			for (int i=deletelocation; i<this.Size-1; i++) 
		//			{
		//				this.ChildKeys[i] = this.ChildKeys[i+1];
		//				this.ChildBufferNumbers[i] = this.ChildBufferNumbers[i+1];
		//			}
		//			this.ChildKeys[this.Size-1] = null;
		//			//this.MaterializedChildNodes[endlocation+1] = null;
		//			//this.ChildBufferNumbers[endlocation+1] = BplusTreeLong.NULLBUFFERNUMBER;
		//			if (this.SizeInUse()<this.Size/2)
		//			{
		//				MergeMe = true;
		//			}
		//			if (deletelocation==0) 
		//			{
		//				result = this.ChildKeys[0];
		//				// this is only relevant for the case of 2-3 trees (empty leaf after deletion)
		//				if (result==null) 
		//				{
		//					result = key; // deleted value
		//				}
		//			}
		//			return result;
		//		}
		/// <summary>
		/// insert key/position entry in self 
		/// </summary>
		/// <param name="key">Key to associate with the leaf</param>
		/// <param name="position">position associated with key in external structur</param>
		/// <param name="splitString">if not null then the smallest key in the new split leaf</param>
		/// <param name="splitNode">if not null then the node was split and this is the leaf to the right.</param>
		/// <returns>null unless the smallest key under this node has changed, in which case it returns the smallest key.</returns>
		public String Insert(String key, long position) //, out String splitString, out BplusNode splitNode) 
			throws Exception
		{
			this.splitString = null;
			this.splitNode = null;
			if (this.isLeaf) 
			{
				return this.InsertLeaf(key, position); //, out splitString, out splitNode);
			}
			int insertposition = this.FindAtOrNextPosition(key, false);
			long insertBufferNumber = this.ChildBufferNumbers[insertposition];
			if (insertBufferNumber==BplusTreeLong.NULLBUFFERNUMBER) 
			{
				throw new BplusTreeException("key not followed by buffer number in non-leaf");
			}
			// insert in subtree
			BplusNode InsertChild = this.MaterializeNodeAtIndex(insertposition);
			BplusNode childSplit;
			String childSplitString;
			String childInsert = InsertChild.Insert(key, position); //, out childSplitString, out childSplit);
			childSplit = InsertChild.splitNode;
			childSplitString = InsertChild.splitString;
			InsertChild.splitNode = null;
			InsertChild.splitString = null;
			// if there was a split the node must expand
			if (childSplit!=null) 
			{
				// insert the child
				this.Soil(); // redundant -- a child will have a change so this node will need to be copied
				int newChildPosition = insertposition+1;
				boolean dosplit = false;
				// if there is no free space we must do a split
				if (this.ChildBufferNumbers[this.Size]!=BplusTreeLong.NULLBUFFERNUMBER) 
				{
					dosplit = true;
					this.PrepareForSplit();
				}
				// bubble over the current values to make space for new child
				for (int i=this.ChildKeys.length-2; i>=newChildPosition-1; i--) 
				{
					int i1 = i+1;
					int i2 = i1+1;
					this.ChildKeys[i1] = this.ChildKeys[i];
					this.ChildBufferNumbers[i2] = this.ChildBufferNumbers[i1];
					BplusNode childNode = this.MaterializedChildNodes[i2] = this.MaterializedChildNodes[i1];
				}
				// record the new child
				this.ChildKeys[newChildPosition-1] = childSplitString;
				//this.MaterializedChildNodes[newChildPosition] = childSplit;
				//this.ChildBufferNumbers[newChildPosition] = childSplit.myBufferNumber;
				childSplit.Reparent(this, newChildPosition);
				// split, if needed
				if (dosplit) 
				{
					int splitpoint = this.MaterializedChildNodes.length/2-1;
					this.splitString = this.ChildKeys[splitpoint];
					this.splitNode = new BplusNode(this.owner, this.parent, -1, this.isLeaf);
					// make copy of expanded node structure
					BplusNode[] materialized = this.MaterializedChildNodes;
					long[] buffernumbers = this.ChildBufferNumbers;
					String[] keys = this.ChildKeys;
					// repair the expanded node
					this.ChildKeys = new String[this.Size];
					this.MaterializedChildNodes = new BplusNode[this.Size+1];
					this.ChildBufferNumbers = new long[this.Size+1];
					this.Clear();
					//Array.Copy(materialized, 0, this.MaterializedChildNodes, 0, splitpoint+1);
					//Array.Copy(buffernumbers, 0, this.ChildBufferNumbers, 0, splitpoint+1);
					for (int i=0; i<splitpoint+1; i++) 
					{
						this.MaterializedChildNodes[i] = materialized[i];
						this.ChildBufferNumbers[i] = buffernumbers[i];
					}
					//Array.Copy(keys, 0, this.ChildKeys, 0, splitpoint);
					for (int i=0; i<splitpoint; i++) 
					{
						this.ChildKeys[i] = keys[i];
					}
					// initialize the new node
					splitNode.Clear(); // redundant.
					int remainingKeys = this.Size-splitpoint;
					//Array.Copy(materialized, splitpoint+1, splitNode.MaterializedChildNodes, 0, remainingKeys+1);
					//Array.Copy(buffernumbers, splitpoint+1, splitNode.ChildBufferNumbers, 0, remainingKeys+1);
					for (int i=0; i<remainingKeys+1; i++) 
					{
						splitNode.MaterializedChildNodes[i] = materialized[i+splitpoint+1];
						splitNode.ChildBufferNumbers[i] = buffernumbers[i+splitpoint+1];
					}
					//Array.Copy(keys, splitpoint+1, splitNode.ChildKeys, 0, remainingKeys);
					for (int i=0; i<remainingKeys; i++) 
					{
						splitNode.ChildKeys[i] = keys[i+splitpoint+1];
					}
					// fix pointers in materialized children of splitnode
					splitNode.reParentAllChildren();
					// store the new node
					splitNode.DumpToFreshBuffer();
					splitNode.CheckIfTerminal();
					splitNode.Soil();
					this.CheckIfTerminal();
				}
				// fix pointers in children
				this.reParentAllChildren();
			}
			if (insertposition==0) 
			{
				// the smallest key may have changed
				return childInsert;
			}
			return null;  // no change in smallest key
		}
		/// <summary>
		/// Check to see if this is a terminal node, if so record it, otherwise forget it
		/// </summary>
		void CheckIfTerminal() 
			throws Exception
		{
			if (!this.isLeaf) 
			{
				for (int i=0; i<this.Size+1; i++) 
				{
					if (this.MaterializedChildNodes[i]!=null) 
					{
						this.owner.ForgetTerminalNode(this);
						return;
					}
				}
			}
			this.owner.RecordTerminalNode(this);
		}
		/// <summary>
		/// insert key/position entry in self (as leaf)
		/// </summary>
		/// <param name="key">Key to associate with the leaf</param>
		/// <param name="position">position associated with key in external structure</param>
		/// <param name="splitString">if not null then the smallest key in the new split leaf</param>
		/// <param name="splitNode">if not null then the node was split and this is the leaf to the right.</param>
		/// <returns>smallest key

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -