#define DS_MODE 2 #include #include #include #include #include #include #include extern char * strdup ( const char *); #define QUIT 0 #define CREATE_STRUCT 1 #define OPEN_STRUCT 2 #define CLOSE_STRUCT 3 #define DELETE_STRUCT 4 #define ADD_VALUE 5 #define REMOVE_VALUE 6 #define FIND_VALUE 7 #define CHG_LIST_TYPE 8 #define CONVERT_TO_TREE 9 #define CONVERT_TO_LIST 10 #define REORG 11 #define INFO 12 #define SHOW 13 #define CHECK 14 #define MANAGER_FILE_NAME "dsbench.so" char DataStruct_Name [100]; char menu [1000]; char buf [100]; long int random ( void ); NDT_Status Module_Manager (va_list Args); void init_menu ( NDT_Root *); int print_menu ( NDT_Root *); /* Mesure des temps d'exécution */ typedef struct { double sec; struct timeval start; struct timeval stop; } T_Cpt; #define t_start(x) {gettimeofday (&(x.start), NULL);} #define t_stop(x) {gettimeofday (&(x.stop), NULL); x.sec = (double)(x.stop.tv_sec) - (double)(x.start.tv_sec) + ((double)(x.stop.tv_usec) - (double)(x.start.tv_usec)) / 1000000;} T_Cpt t_exec; /* Définition des valeurs attachées aux noeuds de la structure */ typedef struct { int Id; char * Nom; } T_Module; int main (int argc, char ** argv) { NDT_Root * Root = NULL; char * tmp; int n, m, i, j; int choice, Nb_Removed, Locked; int Nb_Detected, Nb_Corrected; T_Module * Module, Ref_Module; NDT_Node * Node; if (argc > 1 && !strcmp (argv[1], "-h")) { fprintf (stdout, "Usage : %s [-h] [instance [context]]\n", argv[0]); return 0; } if (DS_Library_Open (0, NULL, DSD_DEBUG_ALL) != NDS_OK) return 0; choice = print_menu (Root); while (choice != QUIT) { switch (choice) { case CREATE_STRUCT: fprintf (stdout, "\nNom de la structure à créer ? "); gets (DataStruct_Name); if (DS_DataStruct_Open (DataStruct_Name, &Root, NDD_DS_LIST | NDD_MN_FIFO, \ MANAGER_FILE_NAME, 0, DSD_CREATE, TRUE) != DSS_OK) printf ("\nNOK\n"); else { strcpy (Root->Manager, "Module_Manager"); printf ("\nStructure créée : OK\n"); } break; case DELETE_STRUCT: if (DS_DataStruct_Close (Root, DSD_DESTROY) == DSS_KO) printf ("\nNOK\n"); else { printf ("\nStructure détruite : OK\n"); Root = NULL; } break; case OPEN_STRUCT: fprintf (stdout, "\nNom de la structure à ouvrir ? "); gets (DataStruct_Name); if (DS_DataStruct_Open (DataStruct_Name, &Root, 0, NULL, 0, DSD_OPEN, TRUE) == NDS_KO) printf ("\nNOK\n"); else printf ("\nStructure ouverte : OK\n"); break; case CLOSE_STRUCT: if (DS_DataStruct_Close (Root, DSD_CLOSE) == DSS_KO) printf ("\nNOK\n"); else { printf ("\nStructure fermée : OK\n"); Root = NULL; } break; case FIND_VALUE: fprintf (stdout, "\nPlage de recherche (?->?) : "); gets (buf); tmp = strstr (buf, "->"); if (tmp != NULL) { * tmp = '\0'; n = atoi (buf); tmp++; tmp++; m = atoi (tmp); if (m < n) { printf ("\nEntrées non valides\n"); break; } } else { printf ("\nEntrées non valides\n"); break; } DS_DataStruct_Lock (Root, DSD_READ, &Locked); i = n; j = m + 1; t_start (t_exec); while (i < j) { Module->Id = n + (random () % m); DS_Node_Find (Root, &Node, Module, NULL); i++; } t_stop (t_exec); DS_DataStruct_Unlock (Root); fprintf (stdout, "\n%d valeur(s) recherchée(s) en %.4f sec (%.2f select/sec)\n", \ m - n + 1, t_exec.sec, (m - n + 1) / t_exec.sec); break; case ADD_VALUE: fprintf (stdout, "\nPlage des valeurs à ajouter (?->?) : "); gets (buf); tmp = strstr (buf, "->"); if (tmp != NULL) { * tmp = '\0'; n = atoi (buf); tmp++; tmp++; m = atoi (tmp); if (m < n) { printf ("\nEntrées non valides\n"); break; } } else { printf ("\nEntrées non valides\n"); break; } DS_DataStruct_Lock (Root, DSD_WRITE, &Locked); fprintf (stdout, "\nOrdre d'ajout (croissant=0 décroissant=1) ? "); gets (buf); choice = atoi (buf); if (choice == 0) { i = n; j = m + 1; t_start (t_exec); while (i < j) { if (DS_Value_Alloc (Root, (void **)&Module, "x", i) == NDS_OK) DS_Value_Add (Root, Module); i++; } t_stop (t_exec); } else { i = m; j = n - 1; t_start (t_exec); while (i > j) { if (DS_Value_Alloc (Root, (void **)&Module, "x", i) == NDS_OK) DS_Value_Add (Root, Module); i--; } t_stop (t_exec); } DS_DataStruct_Unlock (Root); fprintf (stdout, "\n%d valeur(s) ajoutée(s) en %.4f sec (%.2f ajouts/sec)\n", m - n + 1, \ t_exec.sec, (m - n + 1) / t_exec.sec); break; case REMOVE_VALUE: Nb_Removed = 0; fprintf (stdout, "\nPlage des valeurs à supprimer (?->?) : "); gets (buf); tmp = strstr (buf, "->"); if (tmp != NULL) { * tmp = '\0'; n = atoi (buf); tmp++; tmp++; m = atoi (tmp); if (m < n) { printf ("\nEntrées non valides\n"); break; } } else { printf ("\nEntrées non valides\n"); break; } DS_DataStruct_Lock (Root, DSD_WRITE, &Locked); fprintf (stdout, "\nOrdre de suppression (croissant=0 décroissant=1) ? "); gets (buf); choice = atoi (buf); if (choice == 0) { i = n; j = m + 1; t_start (t_exec); while (i < j) { Ref_Module.Id = i; if (DS_Value_Remove (Root, &Ref_Module, (void **)&Module) == NDS_OK) { DS_Value_Free (Root, Module); Nb_Removed++; } i++; } t_stop (t_exec); } else { i = m; j = n - 1; t_start (t_exec); while (i > j) { Ref_Module.Id = i; if (DS_Value_Remove (Root, &Ref_Module, (void **)&Module) == NDS_OK) { DS_Value_Free (Root, Module); Nb_Removed++; } i--; } t_stop (t_exec); } DS_DataStruct_Unlock (Root); fprintf (stdout, "\n%d valeur(s) supprimée(s) en %.4f sec (%.2f suppressions/sec)\n",\ Nb_Removed, t_exec.sec, (m - n + 1) / t_exec.sec); break; case CHG_LIST_TYPE: fprintf (stdout, "\nType de liste (FIFO=0 ; FILO=1 ; triée=2) ? "); gets (buf); choice = atoi (buf); DS_DataStruct_Lock (Root, DSD_WRITE, &Locked); switch (choice) { case 0: Root->Type = NDD_DS_LIST | NDD_MN_FIFO; break; case 1: Root->Type = NDD_DS_LIST | NDD_MN_FILO; break; case 2: Root->Type = NDD_DS_LIST | NDD_MN_ORDERED; break; default: printf ("\nChoix non valide\n"); break; } DS_DataStruct_Unlock (Root); break; case REORG: t_start (t_exec); DS_DataStruct_Lock (Root, DSD_WRITE, &Locked); DS_DataStruct_Reorg (Root); DS_DataStruct_Unlock (Root); t_stop (t_exec); fprintf (stdout, "\nRéorganisation de la structure en %.4f sec\n", t_exec.sec); break; case CONVERT_TO_LIST: t_start (t_exec); DS_DataStruct_Lock (Root, DSD_WRITE, &Locked); DS_DataStruct_Convert (Root, NDD_DS_LIST | NDD_MN_ORDERED); DS_DataStruct_Unlock (Root); t_stop (t_exec); fprintf (stdout, "\nConversion arbre vers liste en %.4f sec\n", t_exec.sec); break; case CONVERT_TO_TREE: t_start (t_exec); DS_DataStruct_Lock (Root, DSD_WRITE, &Locked); DS_DataStruct_Convert (Root, NDD_DS_TREE | NDD_MN_AUTO_EQU); DS_DataStruct_Unlock (Root); t_stop (t_exec); fprintf (stdout, "\nConversion liste vers arbre en %.4f sec\n", t_exec.sec); break; case INFO: DS_DataStruct_Lock (Root, DSD_READ, &Locked); DS_DataStruct_Info_Print (Root, stdout); DS_DataStruct_Unlock (Root); break; case SHOW: DS_DataStruct_Lock (Root, DSD_READ, &Locked); DS_DataStruct_Dump (Root, stdout); DS_DataStruct_Unlock (Root); break; case CHECK: Nb_Corrected = Nb_Detected = 0; ND_DataStruct_Check (Root, &Nb_Detected, &Nb_Corrected, stderr); break; default: fprintf (stdout, "\nChoix %d non défini\n", choice); } choice = print_menu (Root); } DS_Library_Close (); return 0; } NDT_Status Module_Manager (va_list Args) { NDT_Command Command = (NDT_Command) va_arg (Args, NDT_Command); if (Command == NDD_CMD_MAKE_VALUE) { NDT_Root * Root = va_arg (Args, NDT_Root *); T_Module ** Module = va_arg (Args, T_Module **); va_list Value_Args = va_arg (Args, va_list); char * Nom = va_arg (Value_Args, char *); int Id = va_arg (Value_Args, int); if (DS_Alloc (Root, sizeof (T_Module) + strlen (Nom) + 1, (void **)Module) == DSS_OK) { (* Module)->Id = Id; (* Module)->Nom = (char *)((size_t)(*Module) + sizeof (T_Module)); strcpy ((* Module)->Nom, Nom); } return (NDS_OK); } if (Command == NDD_CMD_PRINT_VALUE) { T_Module * Module = (T_Module *) va_arg (Args, void *); FILE * Out = va_arg (Args, FILE *); fprintf (Out, "Id Module=%d Nom Module='%s'", Module->Id, Module->Nom); return (NDS_OK); } if (Command == NDD_CMD_DELETE_VALUE) { NDT_Root * Root = va_arg (Args, NDT_Root *); T_Module * value = (T_Module *) va_arg (Args, void *); DS_Free (Root, value); return (NDS_OK); } if (Command == NDD_CMD_PRINT_INFO) { NDT_Root * Root = va_arg (Args, NDT_Root *); FILE * Out = va_arg (Args, FILE *); char * Root_Type; DST_RootDesc * RootDesc; switch ((int)(Root->Type & NDD_DS_MSK)) { case NDD_DS_LIST : switch ((int)(Root->Type & NDD_MN_MSK)) { case NDD_MN_ORDERED : Root_Type = strdup ("liste triée"); break; case NDD_MN_FILO : Root_Type = strdup ("liste FILO"); break; case NDD_MN_FIFO : Root_Type = strdup ("liste FIFO"); break; default: Root_Type = strdup ("inconnu"); break; } break; case NDD_DS_TREE : switch ((int)(Root->Type & NDD_MN_MSK)) { case NDD_MN_AUTO_EQU : Root_Type = strdup ("arbre auto-équilibré"); break; default: Root_Type = strdup ("arbre non auto-équilibré"); break; } break; default: Root_Type = strdup ("inconnu"); break; } RootDesc = (DST_RootDesc *)(Root->User); fprintf (Out, \ "\nStructure de type %s :\n\t- Nom = %s\n\t- Manager = %s\n\t- Nombre de modules = %ld\n", \ Root_Type, RootDesc->Heap_Name, RootDesc->Manager_FileName, Root->Node_Number); if ((Root->Type & NDD_DS_MSK) == NDD_DS_TREE) fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", \ Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ); if (Root_Type) free (Root_Type); return (NDS_OK); } if (Command == NDD_CMD_COMP_VALUE) { T_Module * Value1, * Value2; long comp; Value1 = (T_Module *) va_arg (Args, void *); Value2 = (T_Module *) va_arg (Args, void *); va_end (Args); comp = Value1->Id - Value2->Id; if (comp < 0) return NDS_LOWER; if (comp > 0) return NDS_GREATER; return NDS_EQUAL; } return (NDS_OK); } void init_menu ( NDT_Root * Root ) { sprintf (menu, "Menu :\n"); sprintf (buf, " - %d) %-30s\n", QUIT, "Quitter"); strcat (menu, buf); sprintf (buf, " - %d) %-30s", CREATE_STRUCT, "Création de structure"); strcat (menu, buf); sprintf (buf, " - %d) %-30s\n", OPEN_STRUCT, "Ouverture de structure"); strcat (menu, buf); if (Root != NULL) { sprintf (buf, " - %d) %-30s", CLOSE_STRUCT, "Fermer la structure"); strcat (menu, buf); sprintf (buf, " - %d) %-30s\n", DELETE_STRUCT, "Détruire la structure"); strcat (menu, buf); sprintf (buf, " - %d) %-30s", ADD_VALUE, "Ajout de valeurs"); strcat (menu, buf); sprintf (buf, " - %d) %-30s\n", REMOVE_VALUE, "Suppression de valeurs"); strcat (menu, buf); sprintf (buf, " - %d) %-30s\n", FIND_VALUE, "Recherche de valeurs aléatoires"); strcat (menu, buf); if (ND_IS_LIST(Root)) { sprintf (buf, " - %d) %-30s", CHG_LIST_TYPE, "Changement de type de liste"); strcat (menu, buf); sprintf (buf, " - %d) %-30s\n", CONVERT_TO_TREE, "Conversion en arbre"); strcat (menu, buf); } else { sprintf (buf, " - %d) %-30s", CONVERT_TO_LIST, "Conversion en liste triée"); strcat (menu, buf); } sprintf (buf, " - %d) %-30s\n", REORG, "Réorganisation"); strcat (menu, buf); sprintf (buf, " - %d) %-30s", INFO, "Informations sur la structure"); strcat (menu, buf); sprintf (buf, " - %d) %-30s\n", SHOW, "Affichage de la structure"); strcat (menu, buf); sprintf (buf, " - %d) %-30s\n", CHECK, "Vérification de la structure"); strcat (menu, buf); } } int print_menu ( NDT_Root * Root ) { init_menu (Root); fprintf (stdout, "\n---------------------------------------------------------\n"); fprintf (stdout, menu); buf [0] = '\0'; while (buf [0] == '\0') { printf ("\nChoice ? "); gets (buf); } return atoi (buf); }