2022-04-23 17:43:38 +02:00
# define _POSIX_C_SOURCE 200809L
2022-04-11 19:19:17 +02:00
# include <time.h>
2022-03-21 01:51:45 +01:00
# include <stdio.h>
# include <stdlib.h>
2022-04-09 00:37:56 +02:00
# include <stdarg.h>
# include <string.h>
2022-04-08 21:32:52 +02:00
# include <errno.h>
2022-04-09 00:37:56 +02:00
# include <pthread.h>
2022-03-21 01:51:45 +01:00
2022-05-07 21:16:35 +02:00
# include "taglialegna.h"
# include "fileQueue.h"
2022-03-21 01:51:45 +01:00
taglia_t * taglia_init ( char * file , int n , . . . ) {
int max_files ;
int max_size ;
int cache_misses ;
taglia_t * new = calloc ( 1 , sizeof ( taglia_t ) ) ;
if ( new = = NULL ) {
2022-05-07 21:16:35 +02:00
perror ( " taglia_init: calloc " ) ;
2022-03-21 01:51:45 +01:00
return NULL ;
}
va_list ap ;
2022-05-07 21:16:35 +02:00
va_start ( ap , n ) ; /* note: by default we have argument promotion,
* but we read only int so thats not a problem */
2022-03-21 01:51:45 +01:00
max_files = ( n < 1 ) ? 0 : va_arg ( ap , int ) ;
max_size = ( n < 2 ) ? 0 : va_arg ( ap , int ) ;
cache_misses = ( n < 3 ) ? 0 : va_arg ( ap , int ) ;
va_end ( ap ) ;
if ( ( new - > file = fopen ( file , " w " ) ) = = NULL ) {
2022-05-07 21:16:35 +02:00
perror ( " taglia_init: fopen " ) ;
2022-03-21 01:51:45 +01:00
goto _error_init ;
}
new - > max_files = max_files ;
new - > max_size = max_size ;
new - > cache_misses = cache_misses ;
if ( pthread_mutex_init ( & new - > m , NULL ) ! = 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " taglia_init: pthread_mutex_init " ) ;
2022-03-21 01:51:45 +01:00
fclose ( new - > file ) ;
goto _error_init ;
}
return new ;
_error_init :
free ( new ) ;
return NULL ;
}
void taglia_del ( taglia_t * taglia ) {
fclose ( taglia - > file ) ;
pthread_mutex_destroy ( & taglia - > m ) ;
free ( taglia ) ;
}
size_t taglia_write ( taglia_t * taglia , char * buf ) {
if ( ! taglia | | ! buf ) {
errno = EINVAL ;
return - 1 ;
}
size_t n = 0 ;
pthread_mutex_lock ( & taglia - > m ) ;
2022-04-27 21:18:25 +02:00
if ( ( n = fwrite ( buf , sizeof ( char ) , strlen ( buf ) , taglia - > file ) ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " taglia_write: fwrite " ) ;
2022-03-21 01:51:45 +01:00
goto _error_write ;
}
pthread_mutex_unlock ( & taglia - > m ) ;
return n ;
_error_write :
pthread_mutex_unlock ( & taglia - > m ) ;
return - 1 ;
}
size_t taglia_log ( taglia_t * taglia , char * buf ) {
if ( ! taglia | | ! buf ) {
errno = EINVAL ;
return - 1 ;
}
time_t now = time ( NULL ) ;
2022-05-07 21:16:35 +02:00
if ( now = = ( time_t ) ( - 1 ) ) {
perror ( " taglia_write: time " ) ;
2022-03-21 01:51:45 +01:00
goto _error_taglia_log ;
}
struct tm tmp_buf ;
struct tm * now_tm ;
now_tm = gmtime_r ( & now , & tmp_buf ) ;
if ( ! now_tm ) {
2022-05-07 21:16:35 +02:00
perror ( " taglia_write: gmtime_r " ) ;
2022-03-21 01:51:45 +01:00
goto _error_taglia_log ;
}
2022-05-07 21:16:35 +02:00
char buff [ 15 ] ; /* 13 only should be strictly needed */
2022-03-21 01:51:45 +01:00
if ( ! strftime ( buff , sizeof ( buff ) , " [%T] " , now_tm ) ) {
2022-05-07 21:16:35 +02:00
perror ( " taglia_write: strftime " ) ;
2022-03-21 01:51:45 +01:00
goto _error_taglia_log ;
}
size_t n , m ;
pthread_mutex_lock ( & taglia - > m ) ;
2022-05-07 21:16:35 +02:00
n = fwrite ( buff , sizeof ( char ) , strnlen ( buff , sizeof ( buff ) ) , taglia - > file ) ;
if ( n < 0 ) {
perror ( " taglia_write: fwrite " ) ;
2022-03-21 01:51:45 +01:00
goto _error_taglia_log_mutex ;
}
2022-05-07 21:16:35 +02:00
m = fwrite ( buf , sizeof ( char ) , strlen ( buf ) , taglia - > file ) ;
if ( m < 0 ) {
perror ( " taglia_write: fwrite " ) ;
2022-03-21 01:51:45 +01:00
goto _error_taglia_log_mutex ;
}
pthread_mutex_unlock ( & taglia - > m ) ;
2022-04-24 01:36:43 +02:00
fflush ( taglia - > file ) ;
2022-03-21 01:51:45 +01:00
return n + m ;
_error_taglia_log_mutex :
pthread_mutex_unlock ( & taglia - > m ) ;
_error_taglia_log :
return - 1 ;
}
int taglia_update ( taglia_t * taglia , queueT * q , int miss ) {
if ( ! taglia | | ! q ) {
errno = EINVAL ;
return - 1 ;
}
pthread_mutex_lock ( & taglia - > m ) ;
size_t len = getLen ( q ) ;
size_t size = getSize ( q ) ;
taglia - > max_files = ( len > taglia - > max_files ) ? len : taglia - > max_files ;
taglia - > max_size = ( size > taglia - > max_size ) ? size : taglia - > max_size ;
2022-04-08 21:32:52 +02:00
taglia - > cache_misses + = ( miss > 0 ) ? miss : 0 ;
2022-03-21 01:51:45 +01:00
pthread_mutex_unlock ( & taglia - > m ) ;
return 0 ;
}
int taglia_stats ( taglia_t * taglia , FILE * stream ) {
if ( ! taglia ) {
errno = EINVAL ;
return - 1 ;
}
pthread_mutex_lock ( & taglia - > m ) ;
double res = ( ( double ) taglia - > max_size ) / ( ( double ) 1000000 ) ;
2022-05-07 21:16:35 +02:00
fprintf ( stream , " Numero di file massimo memorizzato nel server: %zu \n " ,
taglia - > max_files ) ;
/* fprintf(stream, "Dimensione massima in Mbytes raggiunta dal file storage: %.2lf MB\n", res); */
fprintf ( stream , " Dimensione massima in Mbytes raggiunta dal file storage: %lf MB \n " ,
res ) ;
fprintf ( stream , " Numero di volte in cui l’ algoritmo di rimpiazzamento della cache è stato eseguito per selezionare uno o più file \" vittima \" : %zu \n " ,
taglia - > cache_misses ) ;
2022-03-21 01:51:45 +01:00
fflush ( stream ) ;
char tmp_buf [ 2048 ] ;
int n = 0 ;
size_t m = sizeof ( tmp_buf ) ;
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Numero di file massimo memorizzato nel server: %zu \n " ,
taglia - > max_files ) ;
2022-03-21 01:51:45 +01:00
if ( m < n ) goto _error_taglia_stats ;
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Dimensione massima in Mbytes raggiunta dal file storage: %.2lf MB \n " ,
res ) ;
2022-03-21 01:51:45 +01:00
if ( m < n ) goto _error_taglia_stats ;
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Numero di volte in cui l’ algoritmo di rimpiazzamento della cache è stato eseguito per selezionare uno o più file \" vittima \" : %zu \n " ,
taglia - > cache_misses ) ;
2022-03-21 01:51:45 +01:00
if ( m < n ) goto _error_taglia_stats ;
pthread_mutex_unlock ( & taglia - > m ) ;
if ( taglia_write ( taglia , tmp_buf ) < 0 )
return - 1 ;
return 0 ;
_error_taglia_stats :
pthread_mutex_unlock ( & taglia - > m ) ;
2022-05-07 21:16:35 +02:00
perror ( " taglia_stats: snprintf " ) ;
2022-03-21 01:51:45 +01:00
return - 1 ;
}