From: Frederic Marchal Date: Fri, 4 Jan 2013 14:19:21 +0000 (+0100) Subject: Use less memory to store the user strings X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b6b6cb8ce6ff1ae7ace4032808e7cfc80c8b4090;p=thirdparty%2Fsarg.git Use less memory to store the user strings Use the string buffer object to store the strings corresponding to the users. It takes much less memory as the strings only take the exact amount of memory instead of allocating a fixed size buffer as big as the biggest expected string. --- diff --git a/datafile.c b/datafile.c index 72ea06c..4b19ae6 100644 --- a/datafile.c +++ b/datafile.c @@ -44,6 +44,7 @@ void data_file(char *tmp) char *str; char tmp3[MAXLEN]; char u2[MAX_USER_LEN]; + char userlabel[MAX_USER_LEN]; userscan uscan; long long int nbytes=0; long long int nelap=0; @@ -79,7 +80,8 @@ void data_file(char *tmp) ip2name(u2,sizeof(u2)); strcpy(nameantes,u2); } - user_find(uinfo->label,MAX_USER_LEN, u2); + user_find(userlabel,MAX_USER_LEN, u2); + userinfo_label(uinfo,userlabel); if(debug) debuga(_("Reading user file: %s/%s\n"),tmp,uinfo->filename); sort_users_log(tmp,debug,uinfo); diff --git a/include/defs.h b/include/defs.h index 6703159..1161793 100755 --- a/include/defs.h +++ b/include/defs.h @@ -44,15 +44,15 @@ struct generalitemstruct struct userinfostruct { //! The ID of the user as found in the input file. - char id[MAX_USER_LEN]; + const char *id; //! \c True if the ID is in fact the IP address from which the user connected. bool id_is_ip; //! \c True if the user doesn't have a report file. bool no_report; //! The name of the user to display in the report. - char label[MAX_USER_LEN]; + const char *label; //! The mangled name to use in file names of that user. - char filename[MAX_USER_FNAME_LEN]; + const char *filename; //! \c True if this user is in the topuser list. int topuser; //! A general purpose flag that can be set when scanning the user's list. @@ -272,6 +272,7 @@ void useragent(void); // userinfo.c /*@shared@*/struct userinfostruct *userinfo_create(const char *userid); void userinfo_free(void); +void userinfo_label(struct userinfostruct *uinfo,const char *label); /*@shared@*/struct userinfostruct *userinfo_find_from_file(const char *filename); /*@shared@*/struct userinfostruct *userinfo_find_from_id(const char *id); userscan userinfo_startscan(void); diff --git a/redirector.c b/redirector.c index 7415d62..7bff801 100644 --- a/redirector.c +++ b/redirector.c @@ -44,6 +44,7 @@ static void parse_log(FILE *fp_ou,char *buf) const char *url; char user[MAX_USER_LEN]; char ip[45]; + char userlabel[MAX_USER_LEN]; long long int lmon, lday, lyear; int mon, day, year; int idata=0; @@ -207,7 +208,8 @@ static void parse_log(FILE *fp_ou,char *buf) uinfo->id_is_ip=id_is_ip; uinfo->no_report=true; if(Ip2Name && id_is_ip) ip2name(user,sizeof(user)); - user_find(uinfo->label,MAX_USER_LEN, user); + user_find(userlabel,MAX_USER_LEN, user); + userinfo_label(uinfo,userlabel); } fprintf(fp_ou,"%s\t%04d%02d%02d\t%s\t%s\t%s\t",uinfo->id,year,mon,day,hour,ip,url); if (source[0] && list[0]) diff --git a/report.c b/report.c index c6c604b..087290c 100644 --- a/report.c +++ b/report.c @@ -64,6 +64,7 @@ void gerarel(void) char oldaccdiatt[11],oldacchoratt[9]; char tmp3[MAXLEN]; char u2[MAX_USER_LEN]; + char userlabel[MAX_USER_LEN]; long long int nbytes=0; long long int nelap=0; long long int nacc=0; @@ -138,7 +139,8 @@ void gerarel(void) ip2name(u2,sizeof(u2)); strcpy(nameantes,u2); } - user_find(uinfo->label,MAX_USER_LEN, u2); + user_find(userlabel,MAX_USER_LEN, u2); + userinfo_label(uinfo,userlabel); if (!indexonly) { fp_tmp=maketmp(user,tmp,debug); diff --git a/userinfo.c b/userinfo.c index 9117a23..a92ea93 100644 --- a/userinfo.c +++ b/userinfo.c @@ -26,6 +26,7 @@ #include "include/conf.h" #include "include/defs.h" +#include "include/stringbuffer.h" //! The number of users to group in one unit. #define USERS_PER_GROUP 50 @@ -58,6 +59,8 @@ struct userscanstruct static struct usergroupstruct *first_user_group=NULL; //! The counter to generate unique user number when ::AnonymousOutputFiles is set. static int AnonymousCounter=0; +//! String buffer to store the user's related constants. +static StringBufferObject UserStrings=NULL; struct userinfostruct *userinfo_create(const char *userid) { @@ -68,6 +71,15 @@ struct userinfostruct *userinfo_create(const char *userid) int flen; int count, clen; char cstr[9]; + char filename[MAX_USER_FNAME_LEN]; + + if (!UserStrings) { + UserStrings=StringBuffer_Create(); + if (!UserStrings) { + debuga(_("Not enough memory to store the user's strings\n")); + exit(EXIT_FAILURE); + } + } last=NULL; for (group=first_user_group ; group ; group=group->next) { @@ -78,7 +90,7 @@ struct userinfostruct *userinfo_create(const char *userid) if (!group) { group=malloc(sizeof(*group)); if (!group) { - debuga(_("Not enough memory to store the user\n")); + debuga(_("Not enough memory to store user \"%s\"\n"),userid); exit(EXIT_FAILURE); } memset(group,0,sizeof(*group)); @@ -89,42 +101,53 @@ struct userinfostruct *userinfo_create(const char *userid) } user=group->list+group->nusers++; - safe_strcpy(user->id,userid,sizeof(user->id)); + user->id=StringBuffer_Store(UserStrings,userid); + if (!user->id) { + debuga(_("Not enough memory to store user ID \"%s\"\n"),userid); + exit(EXIT_FAILURE); + } + user->label=user->id; //assign a label to avoid a NULL pointer in case none is provided if (AnonymousOutputFiles) { - snprintf(user->filename,sizeof(user->filename),"%d",AnonymousCounter++); + snprintf(filename,sizeof(filename),"%d",AnonymousCounter++); } else { skip=0; j=0; for (i=0 ; userid[i] && jfilename[j++]=userid[i]; + filename[j++]=userid[i]; skip=0; } else { if (!skip) { - user->filename[j++]='_'; + filename[j++]='_'; skip=1; } } } - if (j==0) user->filename[j++]='_'; //don't leave a file name empty - user->filename[j]='\0'; + if (j==0) filename[j++]='_'; //don't leave a file name empty + filename[j]='\0'; flen=i-1; count=0; for (group=first_user_group ; group ; group=group->next) { lastuser=(group->next) ? group->nusers : group->nusers-1; for (i=0 ; ifilename,group->list[i].filename)==0) { + if (strcasecmp(filename,group->list[i].filename)==0) { clen=sprintf(cstr,"-%04X",count++); if (flen+clenfilename+flen,cstr); + strcpy(filename+flen,cstr); else - strcpy(user->filename+MAX_USER_FNAME_LEN-clen,cstr); + strcpy(filename+MAX_USER_FNAME_LEN-clen,cstr); } } } } + user->filename=StringBuffer_Store(UserStrings,filename); + if (!user->filename) + { + debuga(_("Not enough memory to store the file name for user \"%s\"\n"),user->id); + exit(EXIT_FAILURE); + } return(user); } @@ -138,6 +161,23 @@ void userinfo_free(void) free(group); } first_user_group=NULL; + StringBuffer_Destroy(&UserStrings); +} + +/*! + * Store the user's label. + * \param uinfo The user info structure created by userinfo_create(). + * \param label The string label to store. + */ +void userinfo_label(struct userinfostruct *uinfo,const char *label) +{ + if (!uinfo) return; + if (!UserStrings) return; + uinfo->label=StringBuffer_Store(UserStrings,label); + if (!uinfo->label) { + debuga(_("Not enough memory to store label \"%s\" of user \"%s\"\n"),label,uinfo->id); + exit(EXIT_FAILURE); + } } struct userinfostruct *userinfo_find_from_file(const char *filename)