📄 ins_node.htm
字号:
<title>Commented source code for BTPINS</title><h2>Commented source code for <tt>BTPINS</tt></h2><pre> C.BTPINS001 SUBROUTINE BTPINS(ROOT,SIZE,BFILE,DFILE,ID,ITEM)002 * Insert a key into B-tree with nodes in following format:003 * AMC 0: Arbitrary node number.004 * AMC 1: Count of keys in node.005 * AMC 2: Keys, stored as a subvalue list.006 * AMC 3: (number of keys)+1 pointers to next nodes.007 * AMC 4: Pointer to parent node if any.008 INS.ID = ID ;* So we can clobber id while backing up without hurting CALLer009 CALL BTPKEY(ROOT,INS.ID,ITEM,FINDKEY) ;* Get sort string for comparing to rest of tree010 READ NODE.ID FROM BFILE,ROOT ELSE ;* No ptr to root, file must be empty, create empty root011 READ NODE.ID FROM BFILE,"NEXT.ID" ELSE NODE.ID=0012 WRITE (NODE.ID+1) ON BFILE,"NEXT.ID"013 WRITE NODE.ID ON BFILE,ROOT014 WRITE "" ON BFILE,NODE.ID015 END016 BACKINGUP = 0 ;* Flopped true when backtracking for promotions017 NEW.PTR = "" ;* Pointer to sibling when promoting key into parent during backup018 100 READ NODE FROM BFILE,NODE.ID ELSE STOP "Can't find node"019 LEFT = 0 ; RIGHT = NODE<1>+1 ;* Boundaries for binary search of keys in node020 IF RIGHT = 1 THEN POS = 1 ELSE ;* Not an empty root021 LOOP022 POS = INT((LEFT+RIGHT)/2) ;* Find position midway between boundaries023 COMPARE.ID = NODE<2,POS> ;* Get that key024 IF COMPARE.ID = INS.ID THEN ;* Key is already in node025 CRT "Already in node"026 IF BACKINGUP THEN STOP ELSE RETURN027 END028 READ COMPARE.ITEM FROM DFILE, COMPARE.ID ELSE STOP "Can't read"029 CALL BTPKEY(ROOT,COMPARE.ID,COMPARE.ITEM,KEY) ;* Convert COMPARE.ITEM to KEY for comparison030 IS.GREATER = (FINDKEY > KEY) ;* Is our key greater than node key?031 IF IS.GREATER THEN LEFT = POS ELSE RIGHT = POS ;* Adjust search boundaries032 UNTIL (RIGHT-LEFT) <= 1 DO REPEAT033 IF IS.GREATER THEN POS = RIGHT ;* Else POS already OK034 END035 * POS points to where next key should be inserted if this is a leaf036 NEXT.NODE.ID = NODE<3,POS> ;* Key not in this node, get pointer to next node037 IF (NEXT.NODE.ID # "") AND NOT(BACKINGUP) THEN ;* Pointer exists for our downward trip, follow it038 NODE.ID = NEXT.NODE.ID039 GO TO 100040 END041 NODE = INSERT(NODE, 2, POS; INS.ID) ;* Hit a leaf or we've backed up, insert the key042 IF BACKINGUP THEN NODE = INSERT(NODE, 3, POS+1; NEW.PTR) ;* Include ptr to new node043 NODE<1> = NODE<1>+1 ;* Increment count of keys in this node044 IF NODE<1> <= 2*SIZE THEN WRITE NODE ON BFILE,NODE.ID ELSE ;* Node full, split it045 LOOP ;* Create new id for new node046 READ NEW.PTR FROM BFILE,"NEXT.ID" ELSE NEW.PTR=0047 WRITE (NEW.PTR+1) ON BFILE,"NEXT.ID"048 READ NEW.NODE FROM BFILE,NEW.PTR ELSE NEW.NODE=""049 UNTIL NEW.NODE = "" DO REPEAT050 J = 1 ;* Copy right half of overflowed node to new node051 FOR I = SIZE+2 TO (2*SIZE)+2 ;* Range includes last pointer in node052 IF NODE<2,I> # "" THEN NEW.NODE<2,J> = NODE<2,I> ;* I goes past last key, so don't copy nulls053 CHILD.ID = NODE<3,I>054 IF CHILD.ID # "" THEN ;* Not a leaf, copy ptr too055 NEW.NODE<3,J> = CHILD.ID056 READ CHILD FROM BFILE,CHILD.ID ELSE STOP "Can't find"057 CHILD<4> = NEW.PTR ;* Tell child about new parent058 WRITE CHILD ON BFILE, CHILD.ID059 END060 J = J+1061 NEXT I062 NEW.NODE<1> = SIZE ;* Set count in new half-full node063 NEW.NODE<4> = NODE<4> ;* Copy parent id since it's the same064 WRITE NEW.NODE ON BFILE,NEW.PTR ;* Save new node065 INS.ID = NODE<2, SIZE+1> ;* Get median key to promote to parent node066 NEW.NODE = SIZE ;* Drop right half of full node by copying only left half067 FOR I = 1 TO SIZE+1 ;* Range includes last pointer before median068 IF I <= SIZE THEN NEW.NODE<2,I> = NODE<2,I> ;* Keep leftmost half069 IF NODE<3,I> # "" THEN NEW.NODE<3,I> = NODE<3,I> ;* Avoids nulls in leafs070 NEXT I071 NEW.NODE<4> = NODE<4> ;* Remember parent too072 WRITE NEW.NODE ON BFILE,NODE.ID ;* Save only left half of old node073 IF NEW.NODE<4> # "" THEN ;* There's a parent, insert promotee and ptr to new node074 BACKINGUP = 1 ;* Set flag so above code immediately inserts075 NODE.ID = NEW.NODE<4> ;* Get parent id076 GO TO 100077 END078 LOOP ;* We're already in the root, create new one to let tree grow079 READ ROOT.ID FROM BFILE,"NEXT.ID" ELSE ROOT.ID=0080 WRITE (ROOT.ID+1) ON BFILE,"NEXT.ID"081 READ NEW.NODE FROM BFILE,ROOT.ID ELSE NEW.NODE=""082 UNTIL NEW.NODE = "" DO REPEAT083 NEW.NODE<1> = 1084 NEW.NODE<2> = INS.ID085 NEW.NODE<3,1> = NODE.ID086 NEW.NODE<3,2> = NEW.PTR087 WRITE NEW.NODE ON BFILE,ROOT.ID088 WRITE ROOT.ID ON BFILE,ROOT089 READ NEW.NODE FROM BFILE, NODE.ID ELSE STOP "Can't reread"090 NEW.NODE<4> = ROOT.ID ;* Let child know its new parent, the root091 WRITE NEW.NODE ON BFILE, NODE.ID092 READ NEW.NODE FROM BFILE, NEW.PTR ELSE STOP "Can't reread"093 NEW.NODE<4> = ROOT.ID ;* Do same for other child, the newly created node094 WRITE NEW.NODE ON BFILE, NEW.PTR095 END096 RETURN097 END</pre><hr><A HREF="btp.html">B-TREE-P</A> copyright © 1987-1999 by <A HREF="/home/contact.html">Semaphore Corporation</A>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -