Go to the documentation of this file.
43 THashDataEnqueue(&
ctx->spare_q, h);
60 SCLogError(
"Fatal error encountered in THashDataQueueNew. Exiting...");
63 q = THashDataQueueInit(q);
86 BUG_ON(q == NULL || h == NULL);
103 if (q->
len > q->dbg_maxlen)
104 q->dbg_maxlen = q->
len;
168 size_t total_data_size = thash_data_size + data_size;
195 uint32_t data_size = 0;
196 if (h->
data != NULL) {
197 if (
ctx->config.DataSize) {
198 data_size =
ctx->config.DataSize(h->
data);
208 #define THASH_DEFAULT_HASHSIZE 4096
209 #define THASH_DEFAULT_MEMCAP 16777216
210 #define THASH_DEFAULT_PREALLOC 1000
212 #define GET_VAR(prefix,name) \
213 snprintf(varname, sizeof(varname), "%s.%s", (prefix), (name))
224 const char *conf_val;
225 uint32_t configval = 0;
229 if ((
ConfGet(varname, &conf_val)) == 1)
234 "from conf file - %s. Killing engine",
241 GET_VAR(cnf_prefix,
"hash-size");
242 if ((
ConfGet(varname, &conf_val)) == 1)
244 if (
StringParseUint32(&configval, 10, (uint16_t)strlen(conf_val), conf_val) > 0) {
245 ctx->config.hash_size = configval;
249 GET_VAR(cnf_prefix,
"prealloc");
250 if ((
ConfGet(varname, &conf_val)) == 1)
252 if (
StringParseUint32(&configval, 10, (uint16_t)strlen(conf_val), conf_val) > 0) {
253 ctx->config.prealloc = configval;
260 uint64_t hash_size =
ctx->config.hash_size *
sizeof(THashHashRow);
263 "max hash memcap is smaller than projected hash size. "
264 "Memcap: %" PRIu64
", Hash table size %" PRIu64
". Calculate "
265 "total hash size by multiplying \"hash-size\" with %" PRIuMAX
", "
266 "which is the hash bucket size.",
267 SC_ATOMIC_GET(
ctx->config.memcap), hash_size, (uintmax_t)
sizeof(THashHashRow));
272 SCLogError(
"Fatal error encountered in THashInitConfig. Exiting...");
275 memset(
ctx->array, 0,
ctx->config.hash_size *
sizeof(THashHashRow));
278 for (i = 0; i <
ctx->config.hash_size; i++) {
284 for (i = 0; i <
ctx->config.prealloc; i++) {
287 "max thash memcap reached. Memcap %" PRIu64
", "
288 "Memuse %" PRIu64
".",
296 SCLogError(
"preallocating data failed: %s", strerror(errno));
299 THashDataEnqueue(&
ctx->spare_q,h);
306 int (*DataSet)(
void *,
void *),
void (*DataFree)(
void *),
307 uint32_t (*DataHash)(uint32_t,
void *),
bool (*DataCompare)(
void *,
void *),
308 bool (*DataExpired)(
void *,
SCTime_t), uint32_t (*DataSize)(
void *),
bool reset_memcap,
314 ctx->config.data_size = data_size;
315 ctx->config.DataSet = DataSet;
316 ctx->config.DataFree = DataFree;
317 ctx->config.DataHash = DataHash;
318 ctx->config.DataCompare = DataCompare;
319 ctx->config.DataExpired = DataExpired;
320 ctx->config.DataSize = DataSize;
327 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
342 THashDataQueueInit(&
ctx->spare_q);
344 if (THashInitConfig(
ctx, cnf_prefix) < 0) {
367 while ((h = THashDataDequeue(&
ctx->spare_q))) {
369 THashDataFree(
ctx, h);
373 if (
ctx->array != NULL) {
374 for (uint32_t u = 0; u <
ctx->config.hash_size; u++) {
375 h =
ctx->array[u].head;
378 THashDataFree(
ctx, h);
388 THashDataQueueDestroy(&
ctx->spare_q);
400 if (
ctx->array == NULL)
404 for (u = 0; u <
ctx->config.hash_size; u++) {
405 THashHashRow *hb = &
ctx->array[u];
409 char output_string[1024] =
"";
410 int size = FormatterFunc(h->
data, output_string,
sizeof(output_string));
412 if (OutputterFunc(output_ctx, (
const uint8_t *)output_string, size) < 0) {
433 if (
ctx->config.DataExpired == NULL)
439 for (uint32_t i = 0; i <
ctx->config.hash_size; i++) {
440 THashHashRow *hb = &
ctx->array[i];
463 if (
ctx->config.DataSize) {
464 uint32_t data_size =
ctx->config.DataSize(h->
data);
493 if (
ctx->array == NULL)
496 for (u = 0; u <
ctx->config.hash_size; u++) {
497 THashHashRow *hb = &
ctx->array[u];
516 if (
ctx->config.DataSize) {
517 uint32_t data_size =
ctx->config.DataSize(h->
data);
535 static uint32_t THashGetKey(
const THashConfig *cnf,
void *data)
545 static inline int THashCompare(
const THashConfig *cnf,
void *a,
void *b)
563 uint32_t data_size = 0;
564 if (
ctx->config.DataSize) {
565 data_size =
ctx->config.DataSize(data);
569 h = THashDataDequeue(&
ctx->spare_q);
573 h = THashGetUsed(
ctx, data_size);
585 h = THashDataAlloc(
ctx, data_size);
604 SCLogError(
"Adding data will exceed memcap: %" PRIu64
", current memuse: %" PRIu64,
628 uint32_t key = THashGetKey(&
ctx->config,
data);
630 THashHashRow *hb = &
ctx->array[key];
634 if (hb->head == NULL) {
635 h = THashDataGetNew(
ctx,
data);
658 if (THashCompare(&
ctx->config, h->
data,
data) == 0) {
686 if (THashCompare(&
ctx->config, h->
data,
data) != 0) {
737 uint32_t key = THashGetKey(&
ctx->config,
data);
739 THashHashRow *hb = &
ctx->array[key];
742 if (hb->head == NULL) {
751 if (THashCompare(&
ctx->config, h->
data,
data) == 0) {
759 if (THashCompare(&
ctx->config, h->
data,
data) != 0) {
809 uint32_t
cnt =
ctx->config.hash_size;
812 if (++idx >=
ctx->config.hash_size)
815 THashHashRow *hb = &
ctx->array[idx];
851 if (h->
data != NULL) {
852 if (
ctx->config.DataSize) {
853 uint32_t h_data_size =
ctx->config.DataSize(h->
data);
854 if (h_data_size > 0) {
878 uint32_t key = THashGetKey(&
ctx->config,
data);
880 THashHashRow *hb = &
ctx->array[key];
886 if (THashCompare(&
ctx->config, h->
data,
data) == 0) {
912 THashDataFree(
ctx, h);
#define HRLOCK_DESTROY(fb)
void THashCleanup(THashTableContext *ctx)
Cleanup the thash engine.
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
#define HQLOCK_DESTROY(q)
int(* THashOutputFunc)(void *output_ctx, const uint8_t *data, const uint32_t data_len)
int ParseSizeStringU64(const char *size, uint64_t *res)
struct HtpBodyChunk_ * next
int THashRemoveFromHash(THashTableContext *ctx, void *data)
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
void THashConsolidateMemcap(THashTableContext *ctx)
bool(* DataCompare)(void *, void *)
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
#define HRLOCK_UNLOCK(fb)
#define THASH_DEFAULT_HASHSIZE
#define SCMutexUnlock(mut)
#define THASH_DATA_SIZE(ctx)
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
#define GET_VAR(prefix, name)
void THashDataMoveToSpare(THashTableContext *ctx, THashData *h)
#define SCMutexInit(mut, mutattrs)
#define WarnInvalidConfEntry(param_name, format, value)
Generic API that can be used by all to log an invalid conf entry.
void THashShutdown(THashTableContext *ctx)
shutdown the flow engine
#define THASH_DEFAULT_MEMCAP
#define SCMallocAligned(size, align)
struct THashDataGetResult THashGetFromHash(THashTableContext *ctx, void *data)
THashData * THashLookupFromHash(THashTableContext *ctx, void *data)
look up data in the hash
#define THASH_DEFAULT_PREALLOC
#define SCLogError(...)
Macro used to log ERROR messages.
int THashWalk(THashTableContext *ctx, THashFormatFunc FormatterFunc, THashOutputFunc OutputterFunc, void *output_ctx)
Walk the hash.
int(* THashFormatFunc)(const void *in_data, char *output, size_t output_size)
uint32_t(* DataHash)(uint32_t, void *)
#define HRLOCK_TRYLOCK(fb)
uint32_t THashExpire(THashTableContext *ctx, const SCTime_t ts)
expire data from the hash Walk the hash table and remove data that is exprired according to the DataE...
THashTableContext * THashInit(const char *cnf_prefix, size_t data_size, int(*DataSet)(void *, void *), void(*DataFree)(void *), uint32_t(*DataHash)(uint32_t, void *), bool(*DataCompare)(void *, void *), bool(*DataExpired)(void *, SCTime_t), uint32_t(*DataSize)(void *), bool reset_memcap, uint64_t memcap, uint32_t hashsize)
#define THashIncrUsecnt(h)
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
#define THASH_CHECK_MEMCAP(ctx, size)
check if a memory alloc would fit in the memcap
#define DEBUG_VALIDATE_BUG_ON(exp)
THashDataQueue * THashDataQueueNew(void)
#define SCMutexTrylock(mut)