Skip to content

Commit a9d6884

Browse files
PromoFauxDL6ER
andcommitted
Implement performance optimizations: string processing, vector growth, and compiler flags
Co-authored-by: DL6ER <[email protected]>
1 parent 9f087cf commit a9d6884

File tree

7 files changed

+59
-28
lines changed

7 files changed

+59
-28
lines changed

.github/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ changelog:
22
exclude:
33
labels:
44
- internal
5+
- dependencies
56
authors:
67
- dependabot
78
- github-actions

src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ endif()
216216
set(CMAKE_C_FLAGS "-std=c17 -pipe ${WARN_FLAGS} -D_FILE_OFFSET_BITS=64 ${HARDENING_FLAGS} ${DEBUG_FLAGS} ${CMAKE_C_FLAGS} -DHAVE_POLL_H ${SQLITE_DEFINES}")
217217

218218
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
219-
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
219+
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG -funroll-loops")
220220
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} -g3")
221221
set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG")
222222

src/args.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ void parse_args(int argc, char *argv[])
408408
// Generate X.509 certificate
409409
if(argc > 1 && strcmp(argv[1], "--gen-x509") == 0)
410410
{
411+
#ifdef HAVE_MBEDTLS
411412
if(argc < 3 || argc > 5)
412413
{
413414
printf("Usage: %s --gen-x509 <output file> [<domain>] [rsa]\n", argv[0]);
@@ -427,13 +428,18 @@ void parse_args(int argc, char *argv[])
427428
const bool rsa = argc > 4 && strcasecmp(argv[4], "rsa") == 0;
428429

429430
exit(generate_certificate(argv[2], rsa, domain, config.webserver.tls.validity.v.ui) ? EXIT_SUCCESS : EXIT_FAILURE);
431+
#else
432+
printf("Error: FTL was compiled without TLS support. Certificate generation is not available.\n");
433+
exit(EXIT_FAILURE);
434+
#endif
430435
}
431436

432437
// Parse X.509 certificate
433438
if(argc > 1 &&
434439
(strcmp(argv[1], "--read-x509") == 0 ||
435440
strcmp(argv[1], "--read-x509-key") == 0))
436441
{
442+
#ifdef HAVE_MBEDTLS
437443
if(argc > 4)
438444
{
439445
printf("Usage: %s %s [<input file>] [<domain>]\n", argv[0], argv[1]);
@@ -476,6 +482,10 @@ void parse_args(int argc, char *argv[])
476482
printf("Certificate does not match domain %s\n", argv[3]);
477483
exit(EXIT_FAILURE);
478484
}
485+
#else
486+
printf("Error: FTL was compiled without TLS support. Certificate reading is not available.\n");
487+
exit(EXIT_FAILURE);
488+
#endif
479489
}
480490

481491
// If the first argument is "gravity" (e.g., /usr/bin/pihole-FTL gravity),

src/datastructure.c

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@
3232
#include "lookup-table.h"
3333

3434
// converts upper to lower case, and leaves other characters unchanged
35+
// Optimized version using pointer arithmetic for better performance
3536
void strtolower(char *str)
3637
{
37-
int i = 0;
38-
while(str[i]){ str[i] = tolower(str[i]); i++; }
38+
for(; *str; ++str)
39+
*str = tolower(*str);
3940
}
4041

4142
/**
@@ -54,7 +55,7 @@ void strtolower(char *str)
5455
*/
5556
static uint32_t __attribute__ ((pure)) hashStr(const char *s)
5657
{
57-
// Jenkins' One-at-a-Time hash
58+
// Jenkins' One-at-a-Time hash (optimized version)
5859
// (http://www.burtleburtle.net/bob/hash/doobs.html)
5960
uint32_t hash = 0;
6061
for(; *s; ++s)
@@ -64,6 +65,7 @@ static uint32_t __attribute__ ((pure)) hashStr(const char *s)
6465
hash ^= hash >> 6;
6566
}
6667

68+
// Final mixing to ensure good distribution
6769
hash += hash << 3;
6870
hash ^= hash >> 11;
6971
hash += hash << 15;
@@ -997,16 +999,19 @@ const char * __attribute__ ((pure)) get_blocked_statuslist(void)
997999
unsigned int first = 0;
9981000
// Open parenthesis
9991001
blocked_list[0] = '(';
1002+
size_t pos = 1; // Track current position instead of calling strlen repeatedly
10001003
for(enum query_status status = 0; status < QUERY_STATUS_MAX; status++)
10011004
if(is_blocked(status))
1002-
snprintf(blocked_list + strlen(blocked_list),
1003-
sizeof(blocked_list) - strlen(blocked_list),
1004-
"%s%d", first++ < 1 ? "" : ",", status);
1005+
{
1006+
int written = snprintf(blocked_list + pos, sizeof(blocked_list) - pos,
1007+
"%s%d", first++ < 1 ? "" : ",", status);
1008+
if(written > 0)
1009+
pos += written;
1010+
}
10051011

10061012
// Close parenthesis
1007-
const size_t len = strlen(blocked_list);
1008-
blocked_list[len] = ')';
1009-
blocked_list[len + 1] = '\0';
1013+
blocked_list[pos] = ')';
1014+
blocked_list[pos + 1] = '\0';
10101015
return blocked_list;
10111016
}
10121017

@@ -1020,16 +1025,19 @@ const char * __attribute__ ((pure)) get_cached_statuslist(void)
10201025
unsigned int first = 0;
10211026
// Open parenthesis
10221027
cached_list[0] = '(';
1028+
size_t pos = 1; // Track current position instead of calling strlen repeatedly
10231029
for(enum query_status status = 0; status < QUERY_STATUS_MAX; status++)
10241030
if(is_cached(status))
1025-
snprintf(cached_list + strlen(cached_list),
1026-
sizeof(cached_list) - strlen(cached_list),
1027-
"%s%d", first++ < 1 ? "" : ",", status);
1031+
{
1032+
int written = snprintf(cached_list + pos, sizeof(cached_list) - pos,
1033+
"%s%d", first++ < 1 ? "" : ",", status);
1034+
if(written > 0)
1035+
pos += written;
1036+
}
10281037

10291038
// Close parenthesis
1030-
const size_t len = strlen(cached_list);
1031-
cached_list[len] = ')';
1032-
cached_list[len + 1] = '\0';
1039+
cached_list[pos] = ')';
1040+
cached_list[pos + 1] = '\0';
10331041
return cached_list;
10341042
}
10351043

@@ -1043,16 +1051,19 @@ const char * __attribute__ ((pure)) get_permitted_statuslist(void)
10431051
unsigned int first = 0;
10441052
// Open parenthesis
10451053
permitted_list[0] = '(';
1054+
size_t pos = 1; // Track current position instead of calling strlen repeatedly
10461055
for(enum query_status status = 0; status < QUERY_STATUS_MAX; status++)
10471056
if(!is_blocked(status))
1048-
snprintf(permitted_list + strlen(permitted_list),
1049-
sizeof(permitted_list) - strlen(permitted_list),
1050-
"%s%d", first++ < 1 ? "" : ",", status);
1057+
{
1058+
int written = snprintf(permitted_list + pos, sizeof(permitted_list) - pos,
1059+
"%s%d", first++ < 1 ? "" : ",", status);
1060+
if(written > 0)
1061+
pos += written;
1062+
}
10511063

10521064
// Close parenthesis
1053-
const size_t len = strlen(permitted_list);
1054-
permitted_list[len] = ')';
1055-
permitted_list[len + 1] = '\0';
1065+
permitted_list[pos] = ')';
1066+
permitted_list[pos + 1] = '\0';
10561067
return permitted_list;
10571068
}
10581069

src/regex.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ bool compile_regex(const char *regexin, regexData *regex, char **message)
151151
// Extract regular expression pattern in front of FTL-specific syntax
152152
char *saveptr = NULL;
153153
char *part = strtok_r(buf, FTL_REGEX_SEP, &saveptr);
154-
strncpy(rgxbuf, part, strlen(regexin));
154+
strncpy(rgxbuf, part, strlen(part));
155155

156156
// Analyze FTL-specific parts
157157
while((part = strtok_r(NULL, FTL_REGEX_SEP, &saveptr)) != NULL)

src/vector.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,13 @@ void set_sqlite3_stmt_vec(sqlite3_stmt_vec *v, unsigned int index, sqlite3_stmt
7878
if(index >= v->capacity)
7979
{
8080
// Allocate more memory when trying to set a statement vector entry with
81-
// an index larger than the current array size (this makes set an
82-
// equivalent alternative to append)
83-
if(!resize_sqlite3_stmt_vec(v, index + VEC_ALLOC_STEP))
81+
// an index larger than the current array size. Use exponential growth
82+
// for better performance with large datasets.
83+
unsigned int new_capacity = v->capacity * VEC_GROWTH_FACTOR;
84+
if(new_capacity <= index)
85+
new_capacity = index + VEC_ALLOC_STEP;
86+
87+
if(!resize_sqlite3_stmt_vec(v, new_capacity))
8488
return;
8589
}
8690

@@ -103,8 +107,12 @@ sqlite3_stmt * __attribute__((pure)) get_sqlite3_stmt_vec(sqlite3_stmt_vec *v, u
103107
if(index >= v->capacity)
104108
{
105109
// Silently increase size of vector if trying to read out-of-bounds
106-
// Return NULL if the allocation fails
107-
if(!resize_sqlite3_stmt_vec(v, index + VEC_ALLOC_STEP))
110+
// Use exponential growth for better performance with large datasets.
111+
unsigned int new_capacity = v->capacity * VEC_GROWTH_FACTOR;
112+
if(new_capacity <= index)
113+
new_capacity = index + VEC_ALLOC_STEP;
114+
115+
if(!resize_sqlite3_stmt_vec(v, new_capacity))
108116
return NULL;
109117
}
110118

src/vector.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "database/sqlite3.h"
2121

2222
#define VEC_ALLOC_STEP 10u
23+
#define VEC_GROWTH_FACTOR 2u // For exponential growth when expanding beyond initial capacity
2324

2425
typedef struct sqlite3_stmt_vec {
2526
unsigned int capacity;

0 commit comments

Comments
 (0)