summaryrefslogtreecommitdiffstats
path: root/src/structs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/structs.c')
-rw-r--r--src/structs.c91
1 files changed, 71 insertions, 20 deletions
diff --git a/src/structs.c b/src/structs.c
index 83d19b9..650eb88 100644
--- a/src/structs.c
+++ b/src/structs.c
@@ -4,22 +4,28 @@
#define SC_CRLE(c, name) (pthread_rwlock_rdlock(name) ? (SC_LOG(SC_LOG_ERROR,c,SC_I18N_LOCKING " " #name " " SC_I18N_FAILED)||1) :0)
#define SC_CUE(c, name) (pthread_rwlock_unlock(name) ? (SC_LOG(SC_LOG_ERROR,c,SC_I18N_UNLOCKING " " #name " " SC_I18N_FAILED)||1):0)
#define SC_REALLOC_K 1.5 /* constant to dynamically realloc large arrays (new size = current size * K) */
-#define SC_ENGINE_GOOGLE (1 << 0)
/* _Atomic(size_t) sc_mem_max = 100e6; */ /* the really soft memory limit of the program: 100MB - NOT IMPLEMENTED */
#define SC_LOG(t, c, m, ...) sc_push_log(t, c, __func__, __FILE__, __LINE__, 0##__VA_OPT__(1), m __VA_OPT__(,) __VA_ARGS__)
-#define SC_LOG_ERROR (1 << 0)
-#define SC_LOG_WARNING (1 << 1)
-#define SC_LOG_INFO (1 << 2)
-#define SC_LOG_DEBUG (1 << 3)
#define SC_BIGGER_ARRAY(name, type, shallinit) do { \
name = realloc(name, sizeof(name[0])*ceil(name##_sizeof*SC_REALLOC_K)); \
for (size_t i = name##_sizeof; shallinit && (i < ceil(name##_sizeof*SC_REALLOC_K)); i++) \
name[i] = type##_init(); \
name##_sizeof = ceil(name##_sizeof*SC_REALLOC_K); /* ceil je ZELO pomemben, če je chunk 1 recimo */ \
} while (0);
-#define SC_OPT_TYPE unsigned char
-#define SC_OPT_IMAGE (1 << 0)
#define SC_STR(x) #x
+enum sc_opt {
+ SC_ENGINE_GOOGLE = 1 << 0,
+ SC_LOG_ERROR = 1 << 1,
+ SC_LOG_WARNING = 1 << 2,
+ SC_LOG_INFO = 1 << 3,
+ SC_LOG_DEBUG = 1 << 4,
+ SC_OPT_IMAGE = 1 << 5
+};
+#define SC_LOG_MASK (SC_LOG_ERROR | SC_LOG_WARNING | SC_LOG_INFO | SC_LOG_DEBUG)
+#define SC_OPT_TYPE enum sc_opt
+#define SC_OPT_INIT 0
+#define SC_OPT_COMPAR /* mask */ (/* SC_ENGINE_GOOGLE | */ /* any engine is okay */ SC_OPT_IMAGE)
+#define SC_COMPAR_CAST (int (*)(const void *, const void *))
#ifdef SC_LOGMEM
struct sc_logentry {
unsigned char type; /* SC_LOG_ERROR, SC_LOG_WARNING, SC_LOG_INFO, SC_LOG_DEBUG */
@@ -32,6 +38,19 @@ struct sc_logentry {
int sc_logentry_free (struct sc_logentry * l); /* defined in log.c */
struct sc_logentry * sc_logentry_init (); /* defined in log.c */
#endif
+struct sc_cache {
+#ifdef SC_OLD_STORAGE
+ SC_IN_STRUCT_ARRAY(struct sc_query, queries); /* yesfree */
+#else
+ void * qrp; /* queries root pointer-tsearch(3) */
+#endif
+ pthread_rwlock_t * queries_lock;
+#ifdef SC_LOGMEM
+ SC_IN_STRUCT_ARRAY(struct sc_logentry, logentries); /* yesfree */
+ pthread_rwlock_t * logentries_lock;
+#endif
+};
+int sc_push_log (unsigned char t, struct sc_cache * c, const char * ca, char * f, size_t l, unsigned short int isf, char * m, ...);
struct sc_result {
struct sc_query * query; /* nofree - free from sc_cache */
char * url; /* yesfree - url of referer page when image searching */
@@ -65,8 +84,7 @@ struct sc_query {
SC_IN_STRUCT_ARRAY(struct sc_result, results); /* yesfree */
char * string; /* yesfree - query string, stripped of any excess characters that should be excluded from indexing */
time_t lookup_time; /* time of last lookup */
- unsigned char engines; /* with what engine(s) was the query done - bitmask - if there are results from multiple engines */
- SC_OPT_TYPE opt; /* some options */
+ SC_OPT_TYPE opt; /* some options including engines */
};
struct sc_query * sc_query_init () {
struct sc_query * q = calloc(1, sizeof(struct sc_query));
@@ -77,31 +95,60 @@ struct sc_query * sc_query_init () {
q->results[i]->query = q;
}
q->string = NULL;
+ q->opt = SC_OPT_INIT;
return q;
}
-int sc_query_free (struct sc_query * q) {
+#ifdef SC_OLD_STORAGE
+int
+#else
+void
+#endif
+sc_query_free (
+#ifdef SC_OLD_STORAGE
+ struct sc_query
+#else
+ void
+#endif
+ * i) {
+ struct sc_query * q =
+#ifndef SC_OLD_STORAGE
+ (struct sc_query *)
+#endif
+ i;
if (!q)
- return -1;
+ return
+#ifdef SC_OLD_STORAGE
+ -1
+#endif
+ ;
+ if (q->cache)
+ SC_LOG(SC_LOG_DEBUG, q->cache, "sc_query_free: %s", q->string ? q->string : "NULL");
free(q->string); /* if they were not alloced, they are NULL, if they were free'd somewhere else, they are also set to NULL */
for (size_t i = 0; i < q->results_sizeof; i++)
sc_result_free(q->results[i]);
free(q->results);
free(q);
- return 1;
-}
-struct sc_cache {
- SC_IN_STRUCT_ARRAY(struct sc_query, queries); /* yesfree */
- pthread_rwlock_t * queries_lock;
-#ifdef SC_LOGMEM
- SC_IN_STRUCT_ARRAY(struct sc_logentry, logentries); /* yesfree */
- pthread_rwlock_t * logentries_lock;
+ return
+#ifdef SC_OLD_STORAGE
+ 1
#endif
-};
+ ;
+}
+int sc_query_compar (const struct sc_query * a, const struct sc_query * b) {
+#define SC_QUERY_COMPAR_OPT ->opt & SC_OPT_COMPAR
+ int r = (a SC_QUERY_COMPAR_OPT) < (b SC_QUERY_COMPAR_OPT) ? -1
+ : (a SC_QUERY_COMPAR_OPT) > (b SC_QUERY_COMPAR_OPT) ? 1 : 0;
+ if (r) /* first we compare options, because it should be faster than query strings */
+ return r; /* yeah, I know, useless optimizations */
+ return strcmp(a->string, b->string);
+}
struct sc_cache * sc_cache_init() {
#define SC_CILI(name) do { name##_lock = malloc(sizeof(pthread_rwlock_t)); pthread_rwlock_init(name##_lock, NULL); } while (0)
struct sc_cache * c = calloc(1, sizeof(struct sc_cache));
+#ifdef SC_OLD_STORAGE
c->queries_sizeof = SC_ALLOC_CHUNK;
c->queries = calloc(c->queries_sizeof, sizeof(struct sc_query *));
+#endif
#ifdef SC_LOGMEM
c->logentries_sizeof = SC_ALLOC_CHUNK;
c->logentries = calloc(c->logentries_sizeof, sizeof(struct sc_logentry *));
@@ -116,10 +163,14 @@ int sc_cache_free(struct sc_cache * c) {
#define SC_CFLD(name) do { pthread_rwlock_destroy(name##_lock); free(name##_lock); } while(0)
if (!c)
return -1;
+#ifdef SC_OLD_STORAGE
fprintf(stderr, "c->queries_sizeof = %zu\n", c->queries_sizeof);
for (size_t i = 0; i < c->queries_sizeof; i++)
sc_query_free(c->queries[i]);
free(c->queries);
+#else
+ tdestroy(c->qrp, sc_query_free);
+#endif
#ifdef SC_LOGMEM
for (size_t i = 0; i < c->logentries_sizeof; i++)
sc_logentry_free(c->logentries[i]);