//Filename: delete.c //Developer: Jay Suttiruttana #include "btree.h" int main(int argc, char *argv[]) { page_type page, d_parent; Status_type retval; int root, rec_rrn, found_rrn, found_pos, key; if( argc !=2 ) Error("ERROR!"); btopen(); dta_open(); key = atoi(argv[1]); root = getroot(); if(!btsearch(root, key, &found_rrn, &found_pos)) Error("Error. key not found."); /* Search B-Tree for key number */ btread(found_rrn, &page); rec_rrn = page.item[found_pos].rec_rrn; pageinit(&d_parent); /* Initialize dummy parent */ d_parent.child[0] = root; /* Store RRN of the root in dummy parent */ retval = btdelete(key, &d_parent, NIL, 0); if(retval != NO_DEMOTION) { btread(root, &page); /* If concatenation demoted the root, */ if(page.keycount == 0) /* put new root into B-Tree header file */ putroot(page.child[0]); } delete_rec(rec_rrn); /* Remove record from datafile */ printf("\nRicordi %s has been deleted from database!", argv[1]); printf("\nWas located in PAGE %d, POSITION %d\n",found_rrn, found_pos); printf("\n"); dta_close(); btclose(); return(1); } /******************* btdelete: A recursive function to delete an item from B-Tree. *******************/ Status_type btdelete(int key, page_type *parent, int parent_rrn, int parent_pos) { page_type page, sibling, leaf; Status_type retval; int rrn, pos, sibling_rrn, leaf_rrn, i; rrn = parent->child[parent_pos]; if(rrn == NIL) /* Termination condition for recursion */ return(NOT_FOUND); btread(rrn, &page); if(!search_node(key, &page, &pos)) retval = btdelete(key, &page, rrn, pos); else if(page.child[0] != NIL) { /* If key is found in a non-leaf pg.*/ Swap(&page, pos, &leaf, &leaf_rrn); /* swap key with it's successor */ btwrite(rrn, &page); /* Write changes to disk */ btwrite(leaf_rrn, &leaf); retval = btdelete(key, &page, rrn, pos+1); /* Continue with recursion */ } /* until key is found again in a leaf */ else { for(i=pos;i= MINKEYS) { /* if page keycount is at least MINKEYS */ btwrite(rrn, &page); /* deletion is complete, write page */ return(NO_DEMOTION); /* back to B-tree file and return */ } else if(parent_rrn == NIL) { /* if 'page' is the root write page to */ btwrite(rrn, &page); /* B-Tree file and return */ return(retval); } else if(Rdstrbt_Del(&page,parent,parent_pos,&sibling,&sibling_rrn)) { btwrite(parent_rrn, parent); btwrite(rrn, &page); btwrite(sibling_rrn, &sibling); return(NO_DEMOTION); } else { Concatenate(&page, parent, parent_pos, &sibling, &sibling_rrn); btwrite(rrn, &page); FreePage(sibling_rrn); return(DEMOTION); } } /******************************************************************************* Function: delete_rec Task: It deletes a record from datafile *******************************************************************************/ void delete_rec(int rec_rrn) { Record_type del_rec; dta_open(); //Retrieve record from datafile del_rec = RetrievRec(rec_rrn); Show(del_rec); //Clear record fields and set the fifth field to the next list item memset(del_rec.RYOM, 0, FIELD1_SIZE); memset(del_rec.FANNA, 0, FIELD2_SIZE); memset(del_rec.PINCHERLE, 0, FIELD3_SIZE); //Set key field to ****** memset(del_rec.RICORDI, '*', FIELD4_SIZE); del_rec.RICORDI[FIELD4_SIZE-1] = '\0'; //Set the field to the next list item memset(del_rec.TYPE, 0, FIELD5_SIZE); sprintf(del_rec.TYPE, "%d", GetDtaAvlLst()); memset(del_rec.MUS_KEY, 0, FIELD6_SIZE); memset(del_rec.OPUS_NUMBER, 0, FIELD7_SIZE); //Set data available list to deleted record PutDtaAvlLst(rec_rrn); put_total_rec(get_total_rec() - 1); save_record(rec_rrn, del_rec); }