]> git.ipfire.org Git - thirdparty/sarg.git/commitdiff
Use less memory to store the user strings
authorFrederic Marchal <fmarchal@users.sourceforge.net>
Fri, 4 Jan 2013 14:19:21 +0000 (15:19 +0100)
committerFrederic Marchal <fmarchal@users.sourceforge.net>
Fri, 4 Jan 2013 14:19:21 +0000 (15:19 +0100)
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.

datafile.c
include/defs.h
redirector.c
report.c
userinfo.c

index 72ea06ca88831340a15afb3d01028c1eb5fc53e3..4b19ae64221022589dc11f6429824b3ceff42fd7 100644 (file)
@@ -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);
index 670315915ef6d80677bd2484daf471b5d1989bf4..1161793ed7b1b12f592afa2aaea3e3de03000746 100755 (executable)
@@ -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);
index 7415d624fe785b88e6b505fa9714a99fa73f5bff..7bff801630f95cbacfe990f345c463236c0b4a1b 100644 (file)
@@ -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])
index c6c604bf884fd851699b837a6ec71e22a9835526..087290cc682a42becc6bf771932b3dcc53ed9c2a 100644 (file)
--- 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);
index 9117a23614e6ae4f5b257742514049f1f7e5de0e..a92ea9368d66cf47b359595bf3c42bd169c2743d 100644 (file)
@@ -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] && j<MAX_USER_FNAME_LEN-1 ; i++) {
                        if (isalnum(userid[i]) || userid[i]=='-' || userid[i]=='_') {
-                               user->filename[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 ; i<lastuser ; i++) {
-                               if (strcasecmp(user->filename,group->list[i].filename)==0) {
+                               if (strcasecmp(filename,group->list[i].filename)==0) {
                                        clen=sprintf(cstr,"-%04X",count++);
                                        if (flen+clen<MAX_USER_FNAME_LEN)
-                                               strcpy(user->filename+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)