#include <vec/vec.h>
typedef int (*llist_cb)(void * data, void * args);
+typedef void (*llist_destroy_cb)(void * data);
llist_t * llist_new(void);
void llist_free_cb(llist_t * llist, llist_cb cb, void * args);
+void llist_destroy(llist_t * llist, llist_destroy_cb cb);
int llist_append(llist_t * llist, void * data);
int llist_walk(llist_t * llist, llist_cb cb, void * args);
void llist_walkn(llist_t * llist, size_t * n, llist_cb cb, void * args);
#include <siri/db/series.h>
#include <siri/db/db.h>
#include <siri/net/protocol.h>
+#include <siri/inc.h>
+
+#if SIRIDB_EXPR_ALLOC
+#include <llist/llist.h>
+#endif
void siridb_query_run(
uint16_t pid,
cleri_parse_t * pr;
siridb_nodes_t * nodes;
struct timespec start;
+#if SIRIDB_EXPR_ALLOC
+ llist_t * expr_cache;
+#endif
};
#endif /* SIRIDB_QUERY_H_ */
#if CLERI_VERSION_MINOR >= 12
+#if SIRIDB_IS64BIT
#define CLERI_NODE_DATA(__node) ((int64_t)(__node)->data)
#define CLERI_NODE_DATA_ADDR(__node) ((int64_t *) &(__node)->data)
#else
+#define CLERI_NODE_DATA(__node) *((int64_t *)(__node)->data)
+#define CLERI_NODE_DATA_ADDR(__node) ((int64_t *)(__node)->data)
+#endif
+#else
#define CLERI_NODE_DATA(__node) (__node)->result
#define CLERI_NODE_DATA_ADDR(__node) &(__node)->result
#endif
--- /dev/null
+#if UINTPTR_MAX == 0xffffffff
+#define SIRIDB_IS64BIT 0
+#elif UINTPTR_MAX == 0xffffffffffffffff
+#define SIRIDB_IS64BIT 1
+#else
+#define SIRIDB_IS64BIT __WORDSIZE == 64
+#endif
+
+
+#if SIRIDB_IS64BIT
+#define SIRIDB_EXPR_ALLOC 0
+#else
+#define SIRIDB_EXPR_ALLOC CLERI_VERSION_MINOR >= 12
+#endif
#define SIRIDB_VERSION_MAJOR 2
#define SIRIDB_VERSION_MINOR 0
-#define SIRIDB_VERSION_PATCH 38
+#define SIRIDB_VERSION_PATCH 39
/*
* Use SIRIDB_VERSION_PRE_RELEASE for alpha release versions.
* Note that debian alpha packages should use versions like this:
* 2.0.34-0alpha0
*/
-#define SIRIDB_VERSION_PRE_RELEASE ""
+#define SIRIDB_VERSION_PRE_RELEASE "-alpha-0"
#ifndef NDEBUG
#define SIRIDB_VERSION_BUILD_RELEASE "+debug"
free(llist);
}
+/*
+ * Destroys the linked list and calls a call-back function on each item.
+ * The result of the call back function will be ignored.
+ */
+void llist_destroy(llist_t * llist, llist_destroy_cb cb)
+{
+ llist_node_t * node = llist->first;
+ llist_node_t * next;
+
+ while (node != NULL)
+ {
+ cb(node->data);
+ next = node->next;
+ free(node);
+ node = next;
+ }
+ free(llist);
+}
+
/*
* Appends to the end of the list.
*
#include <sys/time.h>
#include <siri/err.h>
+#if SIRIDB_EXPR_ALLOC
+#include <llist/llist.h>
+#endif
+
+
#define QUERY_TOO_LONG -1
#define QUERY_MAX_LENGTH 8192
#define QUERY_EXTRA_ALLOC_SIZE 200
static void QUERY_send_invalid_error(uv_async_t * handle);
static void QUERY_parse(uv_async_t * handle);
-static int QUERY_walk(cleri_node_t * node, siridb_walker_t * walker);
+static int QUERY_walk(
+#if SIRIDB_EXPR_ALLOC
+ siridb_query_t * query,
+#endif
+ cleri_node_t * node,
+ siridb_walker_t * walker);
static int QUERY_to_packer(qp_packer_t * packer, siridb_query_t * query);
static int QUERY_time_expr(
cleri_node_t * node,
return;
}
+ #if SIRIDB_EXPR_ALLOC
+ if ((query->expr_cache = llist_new()) == NULL)
+ {
+ ERR_ALLOC
+ free(query->q);
+ free(query);
+ free(handle);
+ return;
+ }
+ #endif
+
/*
* Set start time.
* (must be real time since we translate now with this value)
cleri_parse_free(query->pr);
}
+ #if SIRIDB_EXPR_ALLOC
+ if (query->expr_cache != NULL)
+ {
+ llist_destroy(query->expr_cache, (llist_destroy_cb) free);
+ }
+ #endif
+
/* decrement client reference counter */
sirinet_stream_decref(query->client);
}
if ((rc = QUERY_walk(
+#if SIRIDB_EXPR_ALLOC
+ query,
+#endif
query->pr->tree->children->node,
walker)))
{
return 0;
}
-static int QUERY_walk(cleri_node_t * node, siridb_walker_t * walker)
+static int QUERY_walk(
+#if SIRIDB_EXPR_ALLOC
+ siridb_query_t * query,
+#endif
+ cleri_node_t * node,
+ siridb_walker_t * walker)
{
int rc;
uint32_t gid;
/* terminate buffer */
buffer[EXPR_MAX_SIZE - size] = 0;
+ #if SIRIDB_EXPR_ALLOC
+ {
+ int64_t * itmp = malloc(sizeof(int64_t));
+ if (itmp == NULL || llist_append(query->expr_cache, itmp))
+ {
+ free(itmp);
+ return EXPR_MEM_ALLOC_ERR;
+ }
+ node->data = itmp;
+ }
+ #endif
+
/* evaluate the expression */
if ((rc = expr_parse(CLERI_NODE_DATA_ADDR(node), buffer)))
{
/* terminate buffer */
buffer[EXPR_MAX_SIZE - size] = 0;
+ #if SIRIDB_EXPR_ALLOC
+ {
+ int64_t * itmp = malloc(sizeof(int64_t));
+ if (itmp == NULL || llist_append(query->expr_cache, itmp))
+ {
+ free(itmp);
+ return EXPR_MEM_ALLOC_ERR;
+ }
+ node->data = itmp;
+ }
+ #endif
+
/* evaluate the expression */
if ((rc = expr_parse(CLERI_NODE_DATA_ADDR(node), buffer)))
{
{
current = current->node->children;
}
- if ((rc = QUERY_walk(current->node, walker)))
+ if ((rc = QUERY_walk(
+#if SIRIDB_EXPR_ALLOC
+ query,
+#endif
+ current->node,
+ walker)))
{
return rc;
}