Commit 132dae00 authored by Geoff Simmons's avatar Geoff Simmons

use header tries to identify headers of interest in the reader thread

parent fae728cb
......@@ -39,6 +39,7 @@
#include "varnishevent.h"
#include "data.h"
#include "hdrtrie.h"
#include "vas.h"
#include "miniobj.h"
......@@ -254,21 +255,20 @@ DATA_Init(void)
CHECK_OBJ(txn[i].recs[j], REC_NODE_MAGIC);
}
for (int j = 0; j < MAX_VSL_TAG; j++) {
include_t *inc;
int idx;
int idx, nhdrs;
idx = tag2idx[j];
if (idx == -1)
continue;
assert(idx < max_idx);
if ((inc = hdr_include_tbl[j]) == NULL) {
nhdrs = HDR_N(hdr_trie[j]);
if (nhdrs == 0) {
txn[i].recs[idx]->hdrs = NULL;
continue;
}
CHECK_OBJ(inc, INCLUDE_MAGIC);
txn[i].recs[idx]->hdrs = (rec_t **) calloc(inc->n + 1,
txn[i].recs[idx]->hdrs = (rec_t **) calloc(nhdrs + 1,
sizeof(rec_t *));
txn[i].recs[idx]->hdrs[inc->n] = magic_end_rec;
txn[i].recs[idx]->hdrs[nhdrs] = magic_end_rec;
}
VSTAILQ_INSERT_TAIL(&freetxhead, &txn[i], freelist);
}
......@@ -283,49 +283,6 @@ DATA_Init(void)
return(0);
}
static inline int
data_get_hdr_idx(char **hdrs, size_t n, const char *s, size_t len)
{
int low = 0, high = n - 1;
while (high >= low) {
int i, cmp;
i = (high + low) >> 1;
if ((cmp = strncasecmp(s, hdrs[i], len)) == 0)
return i;
else if (cmp < 0)
high = i - 1;
else
low = i + 1;
}
return -1;
}
int
DATA_FindHdrIdx(enum VSL_tag_e tag, const char *hdr)
{
const char *b, *e, *s;
if (hdr_include_tbl[tag] == NULL)
return -1;
CHECK_OBJ(hdr_include_tbl[tag], INCLUDE_MAGIC);
b = hdr;
while (*b && isspace(*b))
b++;
e = b;
while (*e && *e != ':' && !isspace(*e))
e++;
s = e;
while (*s && isspace(*s))
s++;
if (*s != ':')
return -1;
if (e - b == 0)
return -1;
return data_get_hdr_idx(hdr_include_tbl[tag]->hdr,
hdr_include_tbl[tag]->n, b, e - b);
}
/*
* take all free entries from the datatable for lockless allocation
*/
......
This diff is collapsed.
......@@ -41,12 +41,13 @@ typedef struct arg_t {
typedef void formatter_f(const tx_t *tx, const arg_t *args, char **s,
size_t *len);
int hidx[MAX_VSL_TAG];
char *get_payload(const rec_t *rec);
rec_t *get_tag(const tx_t *tx, enum VSL_tag_e tag);
char *get_hdr(const tx_t *tx, enum VSL_tag_e tag, int hdr_idx);
char *get_fld(char *str, int n, size_t *len);
char *get_rec_fld(const rec_t *rec, int n, size_t *len);
int hdrcmp(const void *s1, const void *s2);
formatter_f format_b_client;
formatter_f format_b_backend;
......
......@@ -112,22 +112,35 @@ HDR_InsertIdx(struct hdrt_node *hdrt, const char *hdr, int idx)
n = hdr_next(*h);
assert(n >= 0 && n < 64);
hdrt->next[n] = HDR_InsertIdx(hdrt->next[n], ++h, idx);
CHECK_OBJ_NOTNULL(hdrt->next[n], HDRT_NODE_MAGIC);
}
else if (*h == '\0') {
n = hdr_next(*s);
assert(n >= 0 && n < 64);
*s = '\0';
hdrt->next[n] = HDR_InsertIdx(hdrt->next[n], ++s, hdrt->idx);
CHECK_OBJ_NOTNULL(hdrt->next[n], HDRT_NODE_MAGIC);
hdrt->idx = idx;
}
else {
/* XXX: this memcpy/memset stuff is ugly, better allocate the next
table on the heap and just move pointers, which is also
probably more cache-friendly. */
struct hdrt_node *s_next[64];
n = hdr_next(*s);
assert(n >= 0 && n < 64);
*s = '\0';
memcpy(s_next, hdrt->next, 64 * sizeof(struct hdrt_next *));
memset(hdrt->next, 0, 64 * sizeof(struct hdrt_next *));
hdrt->next[n] = HDR_InsertIdx(hdrt->next[n], ++s, hdrt->idx);
CHECK_OBJ_NOTNULL(hdrt->next[n], HDRT_NODE_MAGIC);
memcpy(hdrt->next[n]->next, s_next, 64 * sizeof(struct hdrt_next *));
n = hdr_next(*h);
assert(n >= 0 && n < 64);
AZ(hdrt->next[n]);
hdrt->next[n] = HDR_InsertIdx(hdrt->next[n], ++h, idx);
CHECK_OBJ_NOTNULL(hdrt->next[n], HDRT_NODE_MAGIC);
hdrt->idx = -1;
}
......@@ -150,6 +163,58 @@ HDR_N(struct hdrt_node *hdrt)
return n;
}
static struct vsb *
vsb_dup(struct vsb *vsb)
{
struct vsb *dup = VSB_new_auto();
char *str;
VSB_finish(vsb);
str = strdup(VSB_data(vsb));
VSB_cpy(dup, str);
VSB_clear(vsb);
VSB_cpy(vsb, str);
free(str);
return dup;
}
static void
hdr_traverse(struct hdrt_node *hdrt, struct vsb *sb, struct vsb *prefix)
{
struct vsb *current;
if (hdrt == NULL)
return;
CHECK_OBJ(hdrt, HDRT_NODE_MAGIC);
AN(hdrt->str);
current = vsb_dup(prefix);
VSB_cat(current, hdrt->str);
if (hdrt->idx >= 0) {
struct vsb *word = vsb_dup(current);
VSB_finish(word);
VSB_cat(sb, VSB_data(word));
VSB_cat(sb, ",");
VSB_delete(word);
}
for (int i = 0; i < 64; i++)
if (hdrt->next[i] != NULL) {
struct vsb *next = vsb_dup(current);
char c = i + 32;
if (i + 32 == ':')
c = '~';
VSB_putc(next, tolower(c));
hdr_traverse(hdrt->next[i], sb, next);
}
VSB_delete(current);
}
void
HDR_List(struct hdrt_node *hdrt, struct vsb *sb)
{
struct vsb *p = VSB_new_auto();
hdr_traverse(hdrt, sb, p);
}
void
HDR_Fini(struct hdrt_node *hdrt)
{
......
......@@ -29,6 +29,11 @@
*
*/
#ifndef HDRTRIE_H_INCLUDED
#define HDRTRIE_H_INCLUDED
#include "vsb.h"
struct hdrt_node {
unsigned magic;
#define HDRT_NODE_MAGIC 0x970ec029
......@@ -41,4 +46,7 @@ int HDR_FindIdx(struct hdrt_node *hdrt, const char *hdr);
struct hdrt_node *HDR_InsertIdx(struct hdrt_node *hdrt, const char *hdr,
int idx);
int HDR_N(struct hdrt_node *hdrt);
void HDR_List(struct hdrt_node *hdrt, struct vsb *sb);
void HDR_Fini(struct hdrt_node *hdrt);
#endif
......@@ -19,6 +19,7 @@ test_data_LDADD = \
../data.$(OBJEXT) \
../format.$(OBJEXT) \
../strfTIM.$(OBJEXT) \
../hdrtrie.$(OBJEXT) \
@VARNISH_LIBS@ @VARNISH_LIBVARNISH_LIB@ ${LIBM} -lvarnish
test_format_SOURCES = \
......@@ -30,6 +31,7 @@ test_format_LDADD = \
../strfTIM.$(OBJEXT) \
../base64.$(OBJEXT) \
../data.$(OBJEXT) \
../hdrtrie.$(OBJEXT) \
../format.$(OBJEXT) \
@VARNISH_LIBS@ @VARNISH_LIBVARNISH_LIB@ ${LIBM} -lvarnish
......@@ -46,6 +48,7 @@ test_writer_LDADD = \
../base64.$(OBJEXT) \
../spscq.$(OBJEXT) \
../strfTIM.$(OBJEXT) \
../hdrtrie.$(OBJEXT) \
../writer.$(OBJEXT) \
@VARNISH_LIBS@ @VARNISH_LIBVARNISH_LIB@ ${LIBM} -lvarnish
......
......@@ -23,7 +23,7 @@ fi
# predictable from one run to the next.
CKSUM=$( sed -e 's/\(initializing\) \(.*\)/\1/' $LOG | egrep -v 'Writer: returned|Reader: took|^DEBUG: Allocating' | cksum )
if [ "$CKSUM" != '2449935941 61504698' ]; then
if [ "$CKSUM" != '3648120640 61504698' ]; then
echo "ERROR: Regression test varnishevent log incorrect cksum: $CKSUM"
exit 1
fi
......
This diff is collapsed.
......@@ -392,6 +392,13 @@ static char
MASSERT(HDR_FindIdx(hdrt, "X-Forwarded-H:") == -1);
MASSERT(HDR_FindIdx(hdrt, "X-Forwarded-P:") == -1);
hdrt = HDR_InsertIdx(NULL, "Beresp", 0);
hdrt = HDR_InsertIdx(hdrt, "BerespBody", 1);
hdrt = HDR_InsertIdx(hdrt, "Bereq", 2);
MASSERT(HDR_FindIdx(hdrt, "Beresp:") == 0);
MASSERT(HDR_FindIdx(hdrt, "BerespBody:") == 1);
MASSERT(HDR_FindIdx(hdrt, "Bereq:") == 2);
return NULL;
}
......@@ -430,6 +437,91 @@ static char
hdrt = HDR_InsertIdx(hdrt, "X-Forwarded-Proto", 4);
MASSERT(HDR_N(hdrt) == 4);
hdrt = HDR_InsertIdx(NULL, "Beresp", 0);
hdrt = HDR_InsertIdx(hdrt, "BerespBody", 1);
hdrt = HDR_InsertIdx(hdrt, "Bereq", 2);
MASSERT(HDR_N(hdrt) == 3);
return NULL;
}
static char
*test_HDR_List(void)
{
struct hdrt_node *hdrt;
struct vsb *sb = VSB_new_auto();
printf("... testing HDR_List()\n");
HDR_List(NULL, sb);
VSB_finish(sb);
MASSERT(VSB_error(sb) == 0);
MASSERT(VSB_len(sb) == 0);
VSB_clear(sb);
hdrt = HDR_InsertIdx(NULL, "Foo", 4711);
HDR_List(hdrt, sb);
VSB_finish(sb);
MASSERT(VSB_error(sb) == 0);
MASSERT(strcasecmp(VSB_data(sb), "Foo,") == 0);
#define EXP "Accept,Accept-Charset,Accept-Datetime,Accept-Encoding," \
"Accept-Language,"
VSB_clear(sb);
hdrt = HDR_InsertIdx(NULL, "Accept-Encoding", 1);
hdrt = HDR_InsertIdx(hdrt, "Accept", 2);
hdrt = HDR_InsertIdx(hdrt, "Accept-Charset", 3);
hdrt = HDR_InsertIdx(hdrt, "Accept-Language", 4);
hdrt = HDR_InsertIdx(hdrt, "Accept-Datetime", 5);
HDR_List(hdrt, sb);
VSB_finish(sb);
MASSERT(VSB_error(sb) == 0);
MASSERT(strcasecmp(VSB_data(sb), EXP) == 0);
#undef EXP
#define EXP "Content-Disposition,Content-Encoding,Content-Language," \
"Content-Length,Content-Location,Content-MD5,Content-Range," \
"Content-Type,"
VSB_clear(sb);
hdrt = HDR_InsertIdx(NULL, "Content-Disposition", 1);
hdrt = HDR_InsertIdx(hdrt, "Content-Encoding", 2);
hdrt = HDR_InsertIdx(hdrt, "Content-Language", 3);
hdrt = HDR_InsertIdx(hdrt, "Content-Length", 4);
hdrt = HDR_InsertIdx(hdrt, "Content-Location", 5);
hdrt = HDR_InsertIdx(hdrt, "Content-MD5", 6);
hdrt = HDR_InsertIdx(hdrt, "Content-Range", 7);
hdrt = HDR_InsertIdx(hdrt, "Content-Type", 8);
HDR_List(hdrt, sb);
VSB_finish(sb);
MASSERT(VSB_error(sb) == 0);
MASSERT(strcasecmp(VSB_data(sb), EXP) == 0);
#undef EXP
#define EXP "X-Csrf-Token,X-Forwarded-For,X-Forwarded-Host,X-Forwarded-Proto,"
VSB_clear(sb);
hdrt = HDR_InsertIdx(NULL, "X-Csrf-Token", 1);
hdrt = HDR_InsertIdx(hdrt, "X-Forwarded-For", 2);
hdrt = HDR_InsertIdx(hdrt, "X-Forwarded-Host", 3);
hdrt = HDR_InsertIdx(hdrt, "X-Forwarded-Proto", 4);
HDR_List(hdrt, sb);
VSB_finish(sb);
MASSERT(VSB_error(sb) == 0);
MASSERT(strcasecmp(VSB_data(sb), EXP) == 0);
#undef EXP
#define EXP "Bereq,Beresp,BerespBody,"
VSB_clear(sb);
hdrt = HDR_InsertIdx(NULL, "Beresp", 0);
hdrt = HDR_InsertIdx(hdrt, "BerespBody", 1);
hdrt = HDR_InsertIdx(hdrt, "Bereq", 2);
HDR_List(hdrt, sb);
VSB_finish(sb);
MASSERT(VSB_error(sb) == 0);
MASSERT(strcasecmp(VSB_data(sb), EXP) == 0);
#undef EXP
VSB_delete(sb);
return NULL;
}
......@@ -462,6 +554,7 @@ static const char
mu_run_test(test_HDR_FindIdx);
mu_run_test(test_HDR_InsertIdx);
mu_run_test(test_HDR_N);
mu_run_test(test_HDR_List);
mu_run_test(test_HDR_Fini);
return NULL;
}
......
......@@ -362,7 +362,7 @@ event(struct VSL_data *vsl, struct VSL_transaction * const pt[], void *priv)
if (tx->recs[idx]->rec != NULL)
continue;
if (tx->recs[idx]->hdrs != NULL) {
hdr_idx = DATA_FindHdrIdx(tag, p);
hdr_idx = HDR_FindIdx(hdr_trie[tag], p);
if (hdr_idx == -1)
continue;
if (tx->recs[idx]->hdrs[hdr_idx] != NULL)
......@@ -549,7 +549,6 @@ main(int argc, char *argv[])
struct VSM_data *vsm = NULL;
struct VSL_cursor *cursor;
enum VSL_grouping_e grouping = VSL_g_vxid;
struct vsb *hdrs = VSB_new_auto();
unsigned long last_seen = 0;
double last_t;
......@@ -822,19 +821,15 @@ main(int argc, char *argv[])
int idx = tag2idx[i];
if (idx == -1)
continue;
if (hdr_include_tbl[i] == NULL)
if (hdr_trie[i] == NULL)
LOG_Log(LOG_INFO, "Reading tag %s", VSL_tags[i]);
else {
include_t *inc = hdr_include_tbl[i];
CHECK_OBJ_NOTNULL(inc, INCLUDE_MAGIC);
VSB_clear(hdrs);
for (int j = 0; j < inc->n; j++) {
VSB_cat(hdrs, inc->hdr[j]);
VSB_cat(hdrs, ",");
}
struct vsb *hdrs = VSB_new_auto();
HDR_List(hdr_trie[i], hdrs);
VSB_finish(hdrs);
LOG_Log(LOG_INFO, "Reading tags %s with headers: %s", VSL_tags[i],
VSB_data(hdrs));
VSB_delete(hdrs);
}
}
......
......@@ -40,6 +40,8 @@
#include <signal.h>
#include <sys/time.h>
#include "hdrtrie.h"
#include "vapi/vsl.h"
#include "vqueue.h"
#include "vsb.h"
......@@ -150,14 +152,7 @@ typedef VSTAILQ_HEAD(txhead_s, tx_t) txhead_t;
unsigned tx_occ, rec_occ, chunk_occ, tx_occ_hi, rec_occ_hi, chunk_occ_hi,
global_nfree_tx, global_nfree_rec, global_nfree_chunk;
typedef struct include_s {
unsigned magic;
#define INCLUDE_MAGIC 0x4dd6fe3b
char **hdr;
int n;
} include_t;
include_t *hdr_include_tbl[MAX_VSL_TAG];
struct hdrt_node *hdr_trie[MAX_VSL_TAG];
/* Writer (consumer) waits for this condition when the SPSC queue is empty.
Reader (producer) signals the condition after enqueue. */
......@@ -247,7 +242,6 @@ unsigned DATA_Take_Freechunk(struct chunkhead_s *dst);
void DATA_Return_Freetx(struct txhead_s *returned, unsigned nreturned);
void DATA_Return_Freerec(struct rechead_s *returned, unsigned nreturned);
void DATA_Return_Freechunk(struct chunkhead_s *returned, unsigned nreturned);
int DATA_FindHdrIdx(enum VSL_tag_e, const char *hdr);
void DATA_Dump(void);
/* writer.c */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment