forked from menault/TD2_DEV51_Qualite_Algo
166 lines
4.9 KiB
Markdown
166 lines
4.9 KiB
Markdown
# Complexité Cyclomatique
|
|
## Calcul de la complexité cyclomatique pour chaque fonctions
|
|
----------------
|
|
Pour chaque fonction, un diagramme est proposé dans ping-report/diagrammes/*nom de la fonction approprié*.
|
|
|
|
-- Dans daemon.c
|
|
- create_daemon() : 4
|
|
- ping_request() : 2
|
|
- send_check() : 2
|
|
- check_keep_working() : 4
|
|
- daemon_work() : 3
|
|
- ping-report main() : 5
|
|
- write_pid_file() : 2
|
|
- get_ping_from_temp_log : 12
|
|
- write_ping_log : 3
|
|
- set_stats_ping() : 10
|
|
|
|
Toute fonction non mentionnée dans la liste a une complexité cyclomatique de 1, et donc ne nécessite pas un diagramme.
|
|
|
|
-------------------
|
|
Dans un second temps, on va amélorier la complexité cyclomatique des fonctions les plus lourdes si possible. On va commencer par get_ping_from_temp_log.
|
|
La méthode la plus efficace pour réduire la compléxité cyclomatique d'un programme, outre
|
|
changer la nature du code, est de factoriser la fonction, c'est à dire d'écrire un segment
|
|
du code coûteux dans une fonction à part puis de l'appeler.
|
|
|
|
On a décidé de faire cela pour la boucle while de la fonction. Cela nous donne le code suivant :
|
|
|
|
```c
|
|
void while_from_gpftl(char* read_line, size_t* n, FILE* fd, regex_t* p_reg, regmatch_t* pmatch, size_t* nmatch, int* start, int* end, size_t* size_ping, char* ping){
|
|
while(getline(&read_line,n,fd) != -1){
|
|
|
|
if(read_line == NULL){
|
|
break;
|
|
}
|
|
|
|
/* Exec regex to find ping */
|
|
|
|
if(regexec(p_reg,read_line,*nmatch,pmatch,0) == 0){
|
|
|
|
/* Extract ping position from read line */
|
|
*start = (int) pmatch[1].rm_so;
|
|
*end = (int) pmatch[1].rm_eo;
|
|
*size_ping = (size_t) ((*end) - (*start));
|
|
|
|
/* ping string memory allocation */
|
|
ping = malloc(sizeof(char) * ((*size_ping)+2));
|
|
if(ping == NULL){
|
|
free(read_line);
|
|
read_line = NULL;
|
|
*n = 0;
|
|
break;
|
|
}
|
|
|
|
/* Create ping string */
|
|
(void) strncpy(ping, &read_line[*start], *size_ping);
|
|
ping[*size_ping]='\n';
|
|
ping[*size_ping+1]='\0';
|
|
|
|
/* Free memory */
|
|
free(read_line);
|
|
read_line = NULL;
|
|
*n = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
char* better_get_ping_from_temp_log(){
|
|
/* Variables */
|
|
FILE* fd = NULL;
|
|
char* read_line = NULL;
|
|
size_t n = 0;
|
|
size_t nmatch = 2;
|
|
regex_t* p_reg;
|
|
regmatch_t* pmatch;
|
|
char* ping = NULL;
|
|
int start;
|
|
int end;
|
|
size_t size_ping;
|
|
|
|
/* regex struct memory allocation */
|
|
p_reg = (regex_t *) malloc(sizeof(*p_reg));
|
|
if(p_reg == NULL){
|
|
return ping; /* NULL */
|
|
}
|
|
|
|
/* Open ping log file */
|
|
fd = fopen("/var/log/ping-report/last-ping.log","r");
|
|
if(fd == NULL){
|
|
free(p_reg);
|
|
return ping; /* NULL */
|
|
}
|
|
|
|
/* Construct regex to get ping from log file */
|
|
if(regcomp(p_reg,"time=(.*) ms",REG_EXTENDED) != 0){
|
|
if(p_reg != NULL){
|
|
free(p_reg);
|
|
}
|
|
(void) fclose(fd);
|
|
return ping; /* NULL */
|
|
}
|
|
|
|
/* match info memory allocation */
|
|
pmatch = malloc(sizeof(*pmatch) * nmatch);
|
|
if(pmatch == NULL){
|
|
(void) fclose(fd);
|
|
regfree(p_reg);
|
|
free(p_reg);
|
|
return ping; /* NULL */
|
|
}
|
|
|
|
while_from_gpftl(read_line, &n, fd, p_reg, pmatch, &nmatch, &start, &end, &size_ping, ping);
|
|
|
|
/* free allocated memory */
|
|
regfree(p_reg);
|
|
free(p_reg);
|
|
free(pmatch);
|
|
if(read_line != NULL){
|
|
free(read_line);
|
|
}
|
|
|
|
(void) fclose(fd);
|
|
|
|
/* ping may be null, then it must mean that the ping request was lost */
|
|
return ping;
|
|
}
|
|
```
|
|
|
|
Vous pouvez retrouver le diagramme dans le répertoire ping-report/diagrammes/better_get_ping_from_temp_log.mdj. La complexité cyclomatique de l'algorithme sous cette forme est de 7.
|
|
|
|
On peut appliquer le même principe à set_stats_ping en factorisant le segment suivant de la fonction :
|
|
|
|
```c
|
|
void trop_de_ifs(char* read_line, int* nb_loss, double* ping, int* nb_ping, double* max, double* min, int* nb_high, double* sum){
|
|
if(strcmp(read_line,"LOSS") == 0){
|
|
(*nb_loss)++;
|
|
}else{
|
|
/* Evaluate the ping as a double */
|
|
*ping = strtod(read_line,NULL);
|
|
/* Test null ping */
|
|
if(*ping < 0.1){
|
|
/* Ignore null ping */
|
|
}else{
|
|
/* Number of ping readed (for mean calculation) */
|
|
*nb_ping++;
|
|
/* Max ping */
|
|
if(*ping > *max){
|
|
*max = *ping;
|
|
}
|
|
/* Min ping */
|
|
if(*ping < *min){
|
|
*min = *ping;
|
|
}
|
|
/* Number of ping above 100 ms */
|
|
if(*ping > 100.0){
|
|
*nb_high++;
|
|
}
|
|
/* Sum (for mean calculation) */
|
|
sum += *ping;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Vous pouvez retrouver le diagramme dans le répertoire ping-report/diagrammes/better_set_stats_ping. La complexité cyclomatique de l'algorithme sous cette forme est de 4.
|