File logrotate-3.7.7-hashes.patch of Package logrotate

--- logrotate.c	(revision 259)
+++ logrotate.c	(revision 260)
@@ -46,8 +46,11 @@
     char *baseName;
 };
 
-LIST_HEAD(stateSet, logState) states;
+struct logStates {
+	LIST_HEAD(stateSet, logState) head;
+} **states;
 
+unsigned int hashSize;
 int numLogs = 0;
 int debug = 0;
 char *mailCommand = DEFAULT_MAIL_COMMAND;
@@ -64,6 +67,59 @@
     return 1;
 }
 
+#define HASH_SIZE_MIN 64
+static int allocateHash(void)
+{
+	struct logInfo *log;
+	unsigned int hs;
+	int i;
+
+	hs = 0;
+
+	for (log = logs.tqh_first; log != NULL; log = log->list.tqe_next)
+		hs += log->numFiles;
+
+	hs *= 2;
+
+	/* Enforce some reasonable minimum hash size */
+	if (hs < HASH_SIZE_MIN)
+		hs = HASH_SIZE_MIN;
+
+	states = calloc(hs, sizeof(struct logStates *));
+	if (states == NULL) {
+		message(MESS_ERROR, "could not allocate memory for "
+				"hash table\n");
+		return 1;
+	}
+
+	for (i = 0; i < hs; i++) {
+		states[i] = malloc(sizeof(struct logState));
+		if (states[i] == NULL) {
+			message(MESS_ERROR, "could not allocate memory for "
+				"hash element\n");
+			return 1;
+		}
+		LIST_INIT(&(states[i]->head));
+	}
+
+	hashSize = hs;
+
+	return 0;
+}
+
+#define HASH_CONST 13
+static unsigned hashIndex(const char *fn)
+{
+	unsigned hash = 0;
+
+	while (*fn) {
+		hash *= HASH_CONST;
+		hash += *fn++;
+	}
+
+	return hash % hashSize;
+}
+
 static struct logState *newState(const char *fn)
 {
 	struct tm now = *localtime(&nowSecs);
@@ -92,9 +148,10 @@
 
 static struct logState *findState(const char *fn)
 {
+	unsigned int i = hashIndex(fn);
 	struct logState *p;
 
-	for (p = states.lh_first; p != NULL; p = p->list.le_next)
+	for (p = states[i]->head.lh_first; p != NULL; p = p->list.le_next)
 		if (!strcmp(fn, p->fn))
 			break;
 
@@ -103,7 +160,7 @@
 		if ((p = newState(fn)) == NULL)
 			return NULL;
 
-		LIST_INSERT_HEAD(&states, p, list);
+		LIST_INSERT_HEAD(&(states[i]->head), p, list);
 	}
 
 	return p;
@@ -1313,6 +1370,7 @@
     struct logState *p;
     FILE *f;
     char *chptr;
+    int i;
 
     f = fopen(stateFilename, "w");
     if (!f) {
@@ -1323,27 +1381,29 @@
 
     fprintf(f, "logrotate state -- version 2\n");
 
-    for (p = states.lh_first; p != NULL; p = p->list.le_next) {
-	fputc('"', f);
-	for (chptr = p->fn; *chptr; chptr++) {
-	    switch (*chptr) {
-	    case '"':
-		fputc('\\', f);
-	    }
+	for (i = 0; i < hashSize; i++) {
+		for (p = states[i]->head.lh_first; p != NULL;
+				p = p->list.le_next) {
+			fputc('"', f);
+			for (chptr = p->fn; *chptr; chptr++) {
+				switch (*chptr) {
+				case '"':
+					fputc('\\', f);
+				}
 
-	    fputc(*chptr, f);
+				fputc(*chptr, f);
+			}
+
+			fputc('"', f);
+			fprintf(f, " %d-%d-%d\n",
+			p->lastRotated.tm_year + 1900,
+			p->lastRotated.tm_mon + 1,
+			p->lastRotated.tm_mday);
+		}
 	}
 
-	fputc('"', f);
-	fprintf(f, " %d-%d-%d\n",
-		p->lastRotated.tm_year + 1900,
-		p->lastRotated.tm_mon + 1,
-		p->lastRotated.tm_mday);
-    }
-
-    fclose(f);
-
-    return 0;
+	fclose(f);
+	return 0;
 }
 
 static int readState(char *stateFilename)
@@ -1555,7 +1615,8 @@
     poptFreeContext(optCon);
     nowSecs = time(NULL);
 
-	LIST_INIT(&states);
+	if (allocateHash() != 0)
+		return 1;
 
 	if (readState(stateFile))
 	{
@@ -1577,5 +1639,5 @@
 		rc = 1;
 	}
 	
-    return (rc != 0);
+	return (rc != 0);
 }
openSUSE Build Service is sponsored by