/* */ /* **** btutil.c **** Contient les fonctions utilitaires du programme create_root() -- Obtient et initialise le noeud racine et insere une clef. pageinit() -- Place NOKEY dans tous les espaces "clef" et NIL dans les espaces "fils" search_node() -- Retourne YES si la clef est dans le noeud, sinon retourne NO. Dans chaque cas, la position de la clef est mise dans pos. ins_in_page() -- Insere la clef et le fils droit dans la page. split() -- Scinde le noeud par la creation d'un nouveau noeud et par le déplacement de la moitié des clefs vers ce nouveau noeud. Effectue la promotion de la clef du milieu et du rrn du nouveau noeud. */
/*create_root() -- Obtient et initialise le noeud racine et insere une clef.*/ create_root(clef key, short left, short right) { BTPAGE page; short rrn; rrn = getpage(); pageinit(&page); page.key[0] = key; page.child[0] = left; page.child[1] = right; page.keycount = 1; btwrite(rrn,&page); putroot(rrn); return(rrn); } /* */
/*pageinit(): Place NOKEY dans tous les espaces "clef" et NIL dans les espaces fils */ pageinit(BTPAGE *p_page) /* p_page est un pointer vers une page */ { int j; for (j = 0; j < MAXKEYS; j++) { p_page->key[j].matricule = NIL; p_page->key[j].RRN_Fich_Prin = NIL; p_page->child[j] = NIL; } p_page->child[MAXKEYS] = NIL; return 0; }
/* **** btio.c **** Ce fichier contient les fonctions b-arbre impliquees directement dans les entres/sorties btopen() -- Ouvre le fichier "btree.dat" qui contient le b-arbre. btclose() -- Ferme "btree.dat" getroot() -- Obtient le rrn du noeud racine a partir des deux premiers octets de btree.dat. putroot() -- Place le rrn du noeud racine dans les deux premiers octets de btree.dat. create_tree() -- Cree "btree.dat" ainsi que le noeud racine getpage() -- Obtient le prochain bloc disponible dans "btree.dat" pour une nouvelle page btread() -- Lit le numero rrn de la page a partir de "btree.dat" btwrite() -- Ecrit le numero rrn de la page dans "btree.dat" */
/* */ btopen() -- Ouvre le fichier "btree.dat" qui contient le b-arbre. int btopen(void) { btfd = fopen("btree.dat", "w+b"); return(btfd > 0); } /* */
/*getroot() -- Obtient le rrn du noeud racine a partir des deux premiers octets de btree.dat */ short getroot(void) { short root; fseek(btfd, 0, SEEK_SET); if (fread(&root, sizeof(short), 1, btfd) == 0) { printf("Error: Unable to get root.\007\n"); exit(1); } return root; }
/* */ /* **** driver.c **** Le "pilote" pour la création et la manipulation de b-arbres. Crée ou ouvre un fichier b-arbre. Obtient la clef suivante et appelle la fonction insert pour l'insérer dans l'arbre. Au besoin, driver peut créer une nouvelle racine pour l'arbre. */
/* */ /* **** driver.c **** Le "pilote" pour la création et la manipulation de b-arbres. Crée ou ouvre un fichier b-arbre. Obtient la clef suivante et appelle la fonction insert pour l'inserer dans l'arbre. Au besoin, driver peut créer une nouvelle racine pour l'arbre. */ #include "bt.h" int main() {…… /* ouverture du fichier index*/ if btopen() root = getroot(); else {btfd = fopen(``btree.dat``, ``wb+); root = create_root(key, NIL, NIL); } /* ouverture du fichier principal ETUDIANT.dat ….*/ key = getclef(); /* une première clé..*/ do { promoted = insert(root, key, &promo_rrn, &promo_key); if (promoted) root = create_root(promo_key, root, promo_rrn); key = getclef(); } while(/* le fichier ETUDIANT n est pas épuisé*/); }
/***** insert.c **** Contient la fonction insert() qui insere une clef dans un b-arbre. S'appelle de maniere recursive tant que le bas de l'arbre n'est pas atteint.Alors, insert() insere une clef dans le noeud.Si le noeud est plein, - appelle split() pour scinder le noeud - promouvoi la clef du milieu et le rrn du nouveau noeud */ /* insert() Arguments: rrn: Le rrn de la page dans laquelle on fait l'insertion *promo_r_child: Le fils promu vers le prochain niveau key: La clef a etre inseree ici ou plus bas *promo_key: La clef promue vers le prochain niveau */
insert (short rrn, clef key, short *promo_r_child, clef *promo_key) { BTPAGE page, /* La page actuelle */ newpage; /* La nouvelle page cree dans le cas d'une separation */ int found, promoted; /* Des valeurs boolennes */ short pos, p_b_rrn; /* Le rrn promu d'en dessous */ clef p_b_key; /* La clef promue d'en dessous */ if (rrn == NIL) { /* Une fois passe le bas de l'arbre on promouvoit */ *promo_key = key; /* la premiere clef pour qu'elle soit inseree au niveau d'une feuille */ *promo_r_child = NIL; return (YES); } btread(rrn, &page); found = search_node(key, &page, &pos); if (found) { printf("Error: attempt to insert duplicate key: %d \n\007", key.matricule); return (0); } promoted = insert(page.child[pos], key, &p_b_rrn, &p_b_key); if (!promoted) return (NO); /* Pas de promotion */ if (page.keycount < MAXKEYS) {ins_in_page(p_b_key, p_b_rrn, &page); /* On peux inserer la clef et un */ btwrite(rrn, &page); /* pointer dans cette page. */ return (NO); /* Pas de promotion */ } else {split(p_b_key, p_b_rrn, &page, promo_key, promo_r_child, &newpage); btwrite(rrn, &page); btwrite(*promo_r_child, &newpage); return (YES); /* Une promotion a lieu */ }