470 lines
12 KiB
C
470 lines
12 KiB
C
|
#include <stdio.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <string.h>
|
|||
|
#include <sys/time.h>
|
|||
|
#include <stdarg.h>
|
|||
|
|
|||
|
#define ND_MODE 1
|
|||
|
#include <node.h>
|
|||
|
|
|||
|
VER_INFO_EXPORT (ndbench, "$Revision: 1.1 $", "$Name: $", __FILE__, "$Author: smas $")
|
|||
|
|
|||
|
#define USAGE "Usage : %s [ --help | --version [-v] ]\n"
|
|||
|
|
|||
|
#define QUIT 0
|
|||
|
#define ADD_VALUE 1
|
|||
|
#define REMOVE_VALUE 2
|
|||
|
#define FIND_VALUE 3
|
|||
|
#define CHG_LIST_TYPE 4
|
|||
|
#define CONVERT_TO_TREE 5
|
|||
|
#define CONVERT_TO_LIST 6
|
|||
|
#define REORG 7
|
|||
|
#define INFO 8
|
|||
|
#define SHOW 9
|
|||
|
#define CHECK 10
|
|||
|
|
|||
|
char menu [1000];
|
|||
|
char buf [100];
|
|||
|
NDT_Root * Root;
|
|||
|
long int random (void);
|
|||
|
NDT_Status Module_Manager (va_list);
|
|||
|
void init_menu (void);
|
|||
|
int print_menu (void);
|
|||
|
extern char * strdup (const char *);
|
|||
|
|
|||
|
/* Mesure des temps d'ex<65>cution */
|
|||
|
|
|||
|
typedef struct {
|
|||
|
double sec;
|
|||
|
struct timeval start;
|
|||
|
struct timeval stop;
|
|||
|
} 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;}
|
|||
|
cpt t_exec;
|
|||
|
|
|||
|
/* D<>finition des valeurs attach<63>es aux noeuds de la structure */
|
|||
|
|
|||
|
typedef struct {
|
|||
|
int Id;
|
|||
|
char * Nom;
|
|||
|
} T_Module;
|
|||
|
|
|||
|
int main (int argc, char ** argv)
|
|||
|
{
|
|||
|
char * tmp;
|
|||
|
int n, m, i, j, choice, nb_removed, Nb_Detected, Nb_Corrected;
|
|||
|
T_Module Ref_Module, * Module;
|
|||
|
int Debug = TRUE;
|
|||
|
|
|||
|
/* Lancement de commande en mode batch */
|
|||
|
|
|||
|
if (argc >= 2)
|
|||
|
{
|
|||
|
if (!strcmp (argv[1], "--help"))
|
|||
|
{
|
|||
|
fprintf (stderr, USAGE, argv[0]);
|
|||
|
return 1;
|
|||
|
}
|
|||
|
else if (!strcmp (argv[1], "--version"))
|
|||
|
{
|
|||
|
if (argc >= 3 && !strcmp (argv[2], "-v"))
|
|||
|
return VER_Object_Print (stdout, VERD_VERBOSE);
|
|||
|
else
|
|||
|
return VER_Object_Print (stdout, VERD_MINIMAL);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
fprintf (stderr, USAGE, argv[0]);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* Lancement du menu intercatif */
|
|||
|
|
|||
|
ND_Library_Open (Debug);
|
|||
|
|
|||
|
printf ("\nCr<EFBFBD>ation d'une structure de type liste FIFO...\n");
|
|||
|
ND_DataStruct_Open (&Root, NDD_DS_LIST | NDD_MN_FIFO, NULL, NULL, NULL, TRUE);
|
|||
|
|
|||
|
strcpy (Root->Manager, "Module_Manager");
|
|||
|
|
|||
|
choice = print_menu ();
|
|||
|
|
|||
|
while (choice != QUIT)
|
|||
|
{
|
|||
|
switch (choice)
|
|||
|
{
|
|||
|
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<EFBFBD>es non valides\n");
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf ("\nEntr<EFBFBD>es non valides\n");
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
i = n;
|
|||
|
j = m + 1;
|
|||
|
t_start (t_exec);
|
|||
|
while (i < j)
|
|||
|
{
|
|||
|
NDT_Node *Node;
|
|||
|
Ref_Module.Id = n + (random () % m);
|
|||
|
ND_Node_Find (Root, &Node, &Ref_Module, NULL);
|
|||
|
i++;
|
|||
|
}
|
|||
|
t_stop (t_exec);
|
|||
|
|
|||
|
fprintf (stdout, "\n%d valeur(s) recherch<63>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 <20> ajouter (?->?) : ");
|
|||
|
gets (buf);
|
|||
|
tmp = strstr (buf, "->");
|
|||
|
if (tmp != NULL)
|
|||
|
{
|
|||
|
*tmp = '\0';
|
|||
|
n = atoi (buf);
|
|||
|
tmp++;
|
|||
|
tmp++;
|
|||
|
m = atoi (tmp);
|
|||
|
if (m < n)
|
|||
|
{
|
|||
|
printf ("\nEntr<EFBFBD>es non valides\n");
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf ("\nEntr<EFBFBD>es non valides\n");
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
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 (ND_Value_Alloc (Root, (void **)&Module, "x", i) == NDS_OK)
|
|||
|
ND_Value_Add (Root, Module);
|
|||
|
i++;
|
|||
|
}
|
|||
|
t_stop (t_exec);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
i = m;
|
|||
|
j = n - 1;
|
|||
|
t_start (t_exec);
|
|||
|
while (i > j)
|
|||
|
{
|
|||
|
if (ND_Value_Alloc (Root, (void **)&Module, "x", i) == NDS_OK)
|
|||
|
ND_Value_Add (Root, Module);
|
|||
|
i--;
|
|||
|
}
|
|||
|
t_stop (t_exec);
|
|||
|
}
|
|||
|
fprintf (stdout, "\n%d valeur(s) ajout<75>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 <20> supprimer (?->?) : ");
|
|||
|
gets (buf);
|
|||
|
tmp = strstr (buf, "->");
|
|||
|
if (tmp != NULL)
|
|||
|
{
|
|||
|
*tmp = '\0';
|
|||
|
n = atoi (buf);
|
|||
|
tmp++;
|
|||
|
tmp++;
|
|||
|
m = atoi (tmp);
|
|||
|
if (m < n)
|
|||
|
{
|
|||
|
printf ("\nEntr<EFBFBD>es non valides\n");
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf ("\nEntr<EFBFBD>es non valides\n");
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
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 (ND_Value_Remove (Root, &Ref_Module, (void **)&Module) == NDS_OK)
|
|||
|
{
|
|||
|
nb_removed++;
|
|||
|
ND_Value_Free (Root, Module);
|
|||
|
}
|
|||
|
i++;
|
|||
|
}
|
|||
|
t_stop (t_exec);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
i = m;
|
|||
|
j = n - 1;
|
|||
|
t_start (t_exec);
|
|||
|
while (i > j)
|
|||
|
{
|
|||
|
Ref_Module.Id = i;
|
|||
|
if (ND_Value_Remove (Root, &Ref_Module, (void **)&Module) == NDS_OK)
|
|||
|
{
|
|||
|
nb_removed++;
|
|||
|
ND_Value_Free (Root, Module);
|
|||
|
}
|
|||
|
i--;
|
|||
|
}
|
|||
|
t_stop (t_exec);
|
|||
|
}
|
|||
|
fprintf (stdout, "\n%d valeur(s) supprim<69>e(s) en %.4f sec (%.2f suppressions/sec)\n", \
|
|||
|
m - n + 1, t_exec.sec, (m - n + 1) / t_exec.sec );
|
|||
|
break;
|
|||
|
|
|||
|
case CHG_LIST_TYPE:
|
|||
|
fprintf (stdout, "\nType de liste (FIFO=0 ; FILO=1 ; tri<72>e=2) ? ");
|
|||
|
gets (buf);
|
|||
|
choice = atoi (buf);
|
|||
|
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;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case REORG:
|
|||
|
t_start (t_exec);
|
|||
|
ND_DataStruct_Reorg (Root);
|
|||
|
t_stop (t_exec);
|
|||
|
fprintf (stdout, "\nR<EFBFBD>organisation de la structure en %.4f sec\n", t_exec.sec);
|
|||
|
break;
|
|||
|
|
|||
|
case CONVERT_TO_LIST:
|
|||
|
t_start (t_exec);
|
|||
|
ND_DataStruct_Convert (Root, NDD_DS_LIST | NDD_MN_ORDERED);
|
|||
|
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);
|
|||
|
ND_DataStruct_Convert (Root, NDD_DS_TREE | NDD_MN_AUTO_EQU);
|
|||
|
t_stop (t_exec);
|
|||
|
fprintf (stdout, "\nConversion liste vers arbre en %.4f sec\n", t_exec.sec);
|
|||
|
break;
|
|||
|
|
|||
|
case INFO:
|
|||
|
ND_DataStruct_Info_Print (Root, stdout);
|
|||
|
break;
|
|||
|
|
|||
|
case SHOW:
|
|||
|
ND_DataStruct_Dump (Root, stdout);
|
|||
|
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 ();
|
|||
|
}
|
|||
|
|
|||
|
fprintf (stdout, "\nDestruction de la structure... ");
|
|||
|
printf ("%s\n\n", (ND_DataStruct_Close (Root) == NDS_OK ? "OK" : "NOK"));
|
|||
|
|
|||
|
ND_Library_Close ();
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
NDT_Status Module_Manager (va_list args_ptr)
|
|||
|
{
|
|||
|
NDT_Command Command = (NDT_Command)va_arg (args_ptr, NDT_Command);
|
|||
|
|
|||
|
if (Command == NDD_CMD_MAKE_VALUE)
|
|||
|
{
|
|||
|
NDT_Root * Current_Root = va_arg (args_ptr, NDT_Root *);
|
|||
|
T_Module ** Module = va_arg (args_ptr, T_Module **);
|
|||
|
va_list Args = va_arg (args_ptr, va_list);
|
|||
|
char * Nom = va_arg (Args, char *);
|
|||
|
int Id = va_arg (Args, int);
|
|||
|
|
|||
|
*Module = (T_Module *)malloc (sizeof (T_Module));
|
|||
|
(*Module)->Nom = strdup (Nom);
|
|||
|
(*Module)->Id = Id;
|
|||
|
return NDS_OK;
|
|||
|
}
|
|||
|
|
|||
|
if (Command == NDD_CMD_PRINT_VALUE)
|
|||
|
{
|
|||
|
T_Module * Module = (T_Module *)va_arg (args_ptr, void *);
|
|||
|
FILE * Out = va_arg (args_ptr, FILE *);
|
|||
|
|
|||
|
fprintf (Out, "Id=%d\tNom=\"%s\"", Module->Id, Module->Nom);
|
|||
|
|
|||
|
return NDS_OK;
|
|||
|
}
|
|||
|
|
|||
|
if (Command == NDD_CMD_DELETE_VALUE)
|
|||
|
{
|
|||
|
NDT_Root * Current_Root = va_arg (args_ptr, NDT_Root *);
|
|||
|
T_Module * Module = (T_Module *)va_arg (args_ptr, void *);
|
|||
|
|
|||
|
free (Module->Nom);
|
|||
|
free (Module);
|
|||
|
return NDS_OK;
|
|||
|
}
|
|||
|
|
|||
|
if (Command == NDD_CMD_PRINT_INFO)
|
|||
|
{
|
|||
|
NDT_Root * Current_Root = va_arg (args_ptr, NDT_Root *);
|
|||
|
FILE * Out = va_arg (args_ptr, FILE *);
|
|||
|
char Root_Type[100];
|
|||
|
|
|||
|
switch ((int) (Current_Root->Type & NDD_DS_MSK))
|
|||
|
{
|
|||
|
case NDD_DS_LIST :
|
|||
|
|
|||
|
switch ((int) (Current_Root->Type & NDD_MN_MSK))
|
|||
|
{
|
|||
|
case NDD_MN_ORDERED : strcpy (Root_Type, "liste tri<72>e"); break;
|
|||
|
case NDD_MN_FILO : strcpy (Root_Type, "liste FILO"); break;
|
|||
|
case NDD_MN_FIFO : strcpy (Root_Type, "liste FIFO"); break;
|
|||
|
default: strcpy (Root_Type, "inconnu"); break;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case NDD_DS_TREE :
|
|||
|
|
|||
|
switch ((int) (Current_Root->Type & NDD_MN_MSK))
|
|||
|
{
|
|||
|
case NDD_MN_AUTO_EQU : strcpy (Root_Type, "arbre auto-<2D>quilibr<62>"); break;
|
|||
|
default: strcpy (Root_Type, "arbre non auto-<2D>quilibr<62>"); break;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
default: strcpy (Root_Type, "inconnu"); break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
fprintf (Out, "\nStructure de type %s :\n\t- Nombre de noeuds = %ld\n", Root_Type, Current_Root->Node_Number);
|
|||
|
|
|||
|
if ((Current_Root->Type & NDD_DS_MSK) == NDD_DS_TREE)
|
|||
|
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Diff<66>rence maximale autoris<69>e = %ld\n\t- Nombre d'<27>quilibrages = %ld\n", \
|
|||
|
Current_Root->Max_Depth, Current_Root->Min_Depth, Current_Root->Max_Dif, Current_Root->Nb_Equ);
|
|||
|
|
|||
|
return (NDS_OK);
|
|||
|
}
|
|||
|
|
|||
|
if (Command == NDD_CMD_COMP_VALUE)
|
|||
|
{
|
|||
|
T_Module * Value1, * Value2;
|
|||
|
long comp;
|
|||
|
|
|||
|
Value1 = (T_Module *)va_arg (args_ptr, void *);
|
|||
|
Value2 = (T_Module *)va_arg (args_ptr, void *);
|
|||
|
va_end (args_ptr);
|
|||
|
comp = Value1->Id - Value2->Id;
|
|||
|
if (comp < 0) return NDS_LOWER;
|
|||
|
if (comp > 0) return NDS_GREATER;
|
|||
|
return NDS_EQUAL;
|
|||
|
}
|
|||
|
|
|||
|
va_end (args_ptr);
|
|||
|
return (NDS_OK);
|
|||
|
}
|
|||
|
|
|||
|
void init_menu (void)
|
|||
|
{
|
|||
|
sprintf (menu, "Menu :\n");
|
|||
|
sprintf (buf, "\t- %d) %-30s\n", QUIT, "Quitter"); strcat (menu, buf);
|
|||
|
sprintf (buf, "\t- %d) %-30s", ADD_VALUE, "Ajout de valeurs"); strcat (menu, buf);
|
|||
|
sprintf (buf, "\t- %d) %-30s\n", REMOVE_VALUE, "Suppression de valeurs"); strcat (menu, buf);
|
|||
|
sprintf (buf, "\t- %d) %-30s\n", FIND_VALUE, "Recherche de valeurs al<61>atoires"); strcat (menu, buf);
|
|||
|
if (ND_IS_LIST(Root))
|
|||
|
{
|
|||
|
sprintf (buf, "\t- %d) %-30s", CHG_LIST_TYPE, "Changement de type de liste"); strcat (menu, buf);
|
|||
|
sprintf (buf, "\t- %d) %-30s\n", CONVERT_TO_TREE, "Conversion en arbre"); strcat (menu, buf);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
sprintf (buf, "\t- %d) %-30s\n", CONVERT_TO_LIST, "Conversion en liste tri<72>e"); strcat (menu, buf);
|
|||
|
}
|
|||
|
|
|||
|
sprintf (buf, "\t- %d) %-30s\n", REORG, "R<EFBFBD>organisation"); strcat (menu, buf);
|
|||
|
sprintf (buf, "\t- %d) %-30s", INFO, "Informations sur la structure"); strcat (menu, buf);
|
|||
|
sprintf (buf, "\t- %d) %-30s\n", SHOW, "Affichage de la structure"); strcat (menu, buf);
|
|||
|
sprintf (buf, "\t- %d) %-30s\n", CHECK, "V<EFBFBD>rification de la structure"); strcat (menu, buf);
|
|||
|
}
|
|||
|
|
|||
|
int print_menu (void)
|
|||
|
{
|
|||
|
int choice;
|
|||
|
|
|||
|
init_menu ();
|
|||
|
fprintf (stdout, "\n-----------------------------------------------------------------------\n");
|
|||
|
fprintf (stdout, menu);
|
|||
|
*buf = (char)0;
|
|||
|
while (!*buf)
|
|||
|
{
|
|||
|
printf ("\nChoice ? ");
|
|||
|
gets (buf);
|
|||
|
}
|
|||
|
choice = atoi (buf);
|
|||
|
|
|||
|
return choice;
|
|||
|
}
|