]> git.ipfire.org Git - thirdparty/sarg.git/commitdiff
Add a cache to store the resolved IP addresses
authorFrédéric Marchal <fmarchal@users.sourceforge.net>
Sun, 26 Feb 2012 19:12:12 +0000 (20:12 +0100)
committerFrédéric Marchal <fmarchal@users.sourceforge.net>
Sun, 26 Feb 2012 19:12:12 +0000 (20:12 +0100)
The cache is based on a dichotomic search in an array. I plan to compare
the speed of the dichotomic search with the btree.

CMakeLists.txt
Makefile.in
dichotomic.c [new file with mode: 0644]
include/defs.h
include/dichotomic.h [new file with mode: 0644]
ip2name.c
log.c

index e17d3130905027b1cbb1b4b5e28011e21532da69..cb05c77f20e70678244736c8d072d112e68281f6 100755 (executable)
@@ -51,7 +51,7 @@ SET(SRC util.c log.c report.c topuser.c email.c sort.c html.c
        index.c getconf.c usage.c decomp.c ip2name.c ip2name_dns.c
        useragent.c exclude.c convlog.c totday.c repday.c datafile.c
        indexonly.c splitlog.c lastlog.c topsites.c siteuser.c css.c
-       smartfilter.c denied.c authfail.c charset.c
+       smartfilter.c denied.c authfail.c charset.c dichotomic.c
        redirector.c auth.c download.c grepday.c
        dansguardian_log.c dansguardian_report.c realtime.c btree_cache.c
        usertab.c userinfo.c longline.c url.c)
index 16d3ea56ad52714f01a26850347f191272ccd8e4..4595f81b12cd31d6d32c5714d76a5029f209e120 100644 (file)
@@ -35,7 +35,7 @@ SRCS = util.c log.c report.c topuser.c email.c sort.c html.c \
        index.c getconf.c usage.c decomp.c ip2name.c ip2name_dns.c \
        useragent.c exclude.c convlog.c totday.c repday.c datafile.c\
        indexonly.c splitlog.c lastlog.c topsites.c siteuser.c css.c \
-       smartfilter.c denied.c authfail.c charset.c \
+       smartfilter.c denied.c authfail.c charset.c dichotomic.c \
        redirector.c auth.c download.c grepday.c \
        dansguardian_log.c dansguardian_report.c realtime.c btree_cache.c \
        usertab.c userinfo.c longline.c url.c
diff --git a/dichotomic.c b/dichotomic.c
new file mode 100644 (file)
index 0000000..b81129e
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
+ *                                                            1998, 2012
+ *
+ * SARG donations:
+ *      please look at http://sarg.sourceforge.net/donations.php
+ * Support:
+ *     http://sourceforge.net/projects/sarg/forums/forum/363374
+ * ---------------------------------------------------------------------
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "include/conf.h"
+#include "include/defs.h"
+#include "include/dichotomic.h"
+
+/*!
+One key/value pair stored in the sorted list.
+*/
+struct DichotomicItemStruct
+{
+       //! The key.
+       const char *Key;
+       //! The value.
+       const char *Value;
+};
+
+struct DichotomicStruct
+{
+       //! The array containing the sorted pairs.
+       struct DichotomicItemStruct *Items;
+       //! The number of pairs in the array.
+       int NItems;
+       //! The size of the array.
+       int NAllocated;
+};
+
+/*!
+Create an object to store key/value pairs and
+retrieve them.
+
+\return The object to pass to the functions in this module.
+The returned pointer is NULL if there is not enough memory
+to allocate the object. The object must be freed with a call
+to Dichotomic_Destroy().
+*/
+DichotomicObject Dichotomic_Create(void)
+{
+       DichotomicObject Obj;
+       
+       Obj=malloc(sizeof(*Obj));
+       if (!Obj)
+       {
+               return(NULL);
+       }
+       memset(Obj,0,sizeof(*Obj));
+       return(Obj);
+}
+
+/*!
+Destroy an object created by Dichotomic_Create().
+
+\param ObjPtr The pointer to the variable containing
+the object to destroy. The pointer is reset to NULL
+by this function. It is safe to pass NULL or a NULL
+pointer.
+*/
+void Dichotomic_Destroy(DichotomicObject *ObjPtr)
+{
+       DichotomicObject Obj;
+       int i;
+       
+       if (!ObjPtr || !*ObjPtr) return;
+       Obj=*ObjPtr;
+       *ObjPtr=NULL;
+       if (Obj->Items)
+       {
+               for (i=0 ; i<Obj->NItems ; i++)
+               {
+                       free((void*)Obj->Items[i].Key);
+                       free((void*)Obj->Items[i].Value);
+               }
+               free(Obj->Items);
+       }
+       free(Obj);
+}
+
+static int Dichotomic_FindKeyPos(DichotomicObject Obj,const char *key,bool *Found)
+{
+       int down,up;
+       int middle=0;
+       int cmp=0;
+       
+       down=0;
+       up=Obj->NItems-1;
+       while (up>=down)
+       {
+               middle=(down+up)/2;
+               cmp=strcasecmp(key,Obj->Items[middle].Key);
+               if (!cmp) 
+               {
+                       *Found=true;
+                       return(middle);
+               }
+               if (cmp<0)
+                       up=middle-1;
+               else
+                       down=middle+1;
+       }
+       *Found=false;
+       if (cmp>0) middle++;
+       return(middle);
+}
+
+/*!
+Insert a key/value pair into the array.
+
+\param Obj The object created by Dichotomic_Create().
+\param key The key of the pair.
+\param value The value of the pair.
+
+\return \c True if the pair was inserted or \c false if
+it failed.
+*/
+bool Dichotomic_Insert(DichotomicObject Obj,const char *key, const char *value)
+{
+       int Position;
+       bool Found;
+       int i;
+       
+       if (!Obj) return(false);
+       if (Obj->Items)
+       {
+               Position=Dichotomic_FindKeyPos(Obj,key,&Found);
+               if (Found) return(false);
+       }
+       else
+               Position=0;
+       
+       if (Obj->NItems>=Obj->NAllocated)
+       {
+               struct DichotomicItemStruct *Items;
+               Obj->NAllocated+=25;
+               Items=realloc(Obj->Items,Obj->NAllocated*sizeof(*Items));
+               if (!Items)
+               {
+                       debuga(_("Not enough memory to store the key/value pair %s/%s\n"),key,value);
+                       exit(EXIT_FAILURE);
+               }
+               Obj->Items=Items;
+       }
+       
+       for (i=Obj->NItems ; i>Position ; i--)
+       {
+               Obj->Items[i].Key=Obj->Items[i-1].Key;
+               Obj->Items[i].Value=Obj->Items[i-1].Value;
+       }
+       Obj->Items[Position].Key=strdup(key);
+       Obj->Items[Position].Value=strdup(value);
+       if (!Obj->Items[Position].Key || !Obj->Items[Position].Value)
+       {
+               debuga(_("Not enough memory to store the key/value pair %s/%s\n"),key,value);
+               exit(EXIT_FAILURE);
+       }
+       Obj->NItems++;
+       
+       return(true);
+}
+
+/*!
+Search for the value of a key.
+
+\param Obj The object created by Dichotomic_Create().
+\param key The key to search for.
+
+\return The value of the key or NULL if the key was not found.
+*/
+const char *Dichotomic_Search(DichotomicObject Obj,const char *key)
+{
+       int Position;
+       bool Found;
+       
+       if (!Obj) return(NULL);
+       if (Obj->NItems==0 || !Obj->Items) return(NULL);
+       Position=Dichotomic_FindKeyPos(Obj,key,&Found);
+       if (!Found) return(NULL);
+       return(Obj->Items[Position].Value);
+}
index 8e3fdf38b00ae1c371ba1059b53f6e1c84701e26..69acaca0a264e2fc164a694ed0ffd2970ee5dbca 100755 (executable)
@@ -153,6 +153,7 @@ void index_only(const char *dirname,int debug);
 int ip2name_config(const char *param);
 void ip2name_forcedns(void);
 void ip2name(char *ip,int ip_len);
+void ip2name_cleanup(void);
 void name2ip(char *name,int name_size);
 
 // lastlog.c
diff --git a/include/dichotomic.h b/include/dichotomic.h
new file mode 100644 (file)
index 0000000..48c14de
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef DICHOTOMIC_HEADER
+#define DICHOTOMIC_HEADER
+
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#else
+typedef int bool;
+#ifndef true
+#define true 1
+#endif
+#ifndef false
+#define false 0
+#endif
+#endif
+
+//! The object to store key/value pairs
+typedef struct DichotomicStruct *DichotomicObject;
+
+DichotomicObject Dichotomic_Create(void);
+void Dichotomic_Destroy(DichotomicObject *ObjPtr);
+
+const char *Dichotomic_Search(DichotomicObject Obj,const char *key);
+bool Dichotomic_Insert(DichotomicObject Obj,const char *key, const char *value);
+
+
+#endif //DICHOTOMIC_HEADER
index 205574ee813bbdcb10ee09e9f8db49e978d5b2b7..5e7825e4d1346373f43b5589afd3b0d11b32b06e 100644 (file)
--- a/ip2name.c
+++ b/ip2name.c
@@ -27,6 +27,7 @@
 #include "include/conf.h"
 #include "include/defs.h"
 #include "include/ip2name.h"
+#include "include/dichotomic.h"
 
 //! Associate a name or alias to a module.
 struct Ip2NameModules
@@ -49,6 +50,8 @@ static const struct Ip2NameModules ModulesList[]=
 
 //! The chain of the configured modules to try to resolve an IP.
 static struct Ip2NameProcess *FirstModule=NULL;
+//! The list of the names found so far.
+static DichotomicObject KnownIp=NULL;
 
 /*!
 Add a new module to the list of the configured modules.
@@ -182,13 +185,40 @@ void ip2name(char *ip,int ip_len)
 {
        struct Ip2NameProcess *Module;
        enum ip2name_retcode Status;
+       const char *Name;
+       char OrigIp[80];
        
+       if (!KnownIp) {
+               KnownIp=Dichotomic_Create();
+               if (!KnownIp) {
+                       debuga(_("Not enough memory to store the names corresponding to the IP address\n"));
+                       exit(EXIT_FAILURE);
+               }
+       }
+       
+       Name=Dichotomic_Search(KnownIp,ip);
+       if (Name) {
+               safe_strcpy(ip,Name,ip_len);
+               return;
+       }
+       
+       safe_strcpy(OrigIp,ip,sizeof(OrigIp));
        for (Module=FirstModule ; Module ; Module=Module->Next) {
                if (Module->Resolve) {
                        Status=Module->Resolve(ip,ip_len);
-                       if (Status==INRC_Found) return;
+                       if (Status==INRC_Found) break;
                }
        }
+       Dichotomic_Insert(KnownIp,OrigIp,ip);
+}
+
+/*!
+Release the memory allocated to resolve the IP addresses
+into names.
+*/
+void ip2name_cleanup(void)
+{
+       Dichotomic_Destroy(&KnownIp);
 }
 
 void name2ip(char *name,int name_size)
diff --git a/log.c b/log.c
index e2172e6d6cc77fa101333175b57fc9554b53df2a..5913241de45f66f5a986e87ba682aabdbe55f37f 100644 (file)
--- a/log.c
+++ b/log.c
@@ -1708,6 +1708,7 @@ int main(int argc,char *argv[])
                unlinkdir(tmp,0);
        }
 
+       ip2name_cleanup();
        free_hostalias();
        userinfo_free();
        if(userfile)