@ -35,7 +35,7 @@
# include "util-hash-lookup3.h"
# include "util-validate.h"
static THashData * THashGetUsed ( THashTableContext * ctx );
static THashData * THashGetUsed ( THashTableContext * ctx , uint32_t data_size );
static void THashDataEnqueue ( THashDataQueue * q , THashData * h ) ;
void THashDataMoveToSpare ( THashTableContext * ctx , THashData * h )
@ -157,17 +157,19 @@ static uint32_t THashDataQueueLen(THashDataQueue *q)
}
# endif
static THashData * THashDataAlloc ( THashTableContext * ctx )
static THashData * THashDataAlloc ( THashTableContext * ctx , uint32_t data_size )
{
const size_t data_size = THASH_DATA_SIZE ( ctx ) ;
const size_t thash_ data_size = THASH_DATA_SIZE ( ctx ) ;
if ( ! ( THASH_CHECK_MEMCAP ( ctx , data_size) ) ) {
if ( ! ( THASH_CHECK_MEMCAP ( ctx , thash_data_size + data_size) ) ) {
return NULL ;
}
( void ) SC_ATOMIC_ADD ( ctx - > memuse , data_size ) ;
size_t total_data_size = thash_data_size + data_size ;
THashData * h = SCCalloc ( 1 , data_size ) ;
( void ) SC_ATOMIC_ADD ( ctx - > memuse , total_data_size ) ;
THashData * h = SCCalloc ( 1 , thash_data_size ) ;
if ( unlikely ( h = = NULL ) )
goto error ;
@ -181,6 +183,7 @@ static THashData *THashDataAlloc(THashTableContext *ctx)
return h ;
error :
( void ) SC_ATOMIC_SUB ( ctx - > memuse , total_data_size ) ;
return NULL ;
}
@ -189,12 +192,16 @@ static void THashDataFree(THashTableContext *ctx, THashData *h)
if ( h ! = NULL ) {
DEBUG_VALIDATE_BUG_ON ( SC_ATOMIC_GET ( h - > use_cnt ) ! = 0 ) ;
uint32_t data_size = 0 ;
if ( h - > data ! = NULL ) {
if ( ctx - > config . DataSize ) {
data_size = ctx - > config . DataSize ( h - > data ) ;
}
ctx - > config . DataFree ( h - > data ) ;
}
SCMutexDestroy ( & h - > m ) ;
SCFree ( h ) ;
( void ) SC_ATOMIC_SUB ( ctx - > memuse , THASH_DATA_SIZE ( ctx ) ) ;
( void ) SC_ATOMIC_SUB ( ctx - > memuse , THASH_DATA_SIZE ( ctx ) + ( uint64_t ) data_size ) ;
}
}
@ -268,7 +275,7 @@ static int THashInitConfig(THashTableContext *ctx, const char *cnf_prefix)
for ( i = 0 ; i < ctx - > config . hash_size ; i + + ) {
HRLOCK_INIT ( & ctx - > array [ i ] ) ;
}
( void ) SC_ATOMIC_ADD ( ctx - > memuse , ( ctx - > config . hash_size * sizeof ( THashHashRow ) ) ) ;
( void ) SC_ATOMIC_ADD ( ctx - > memuse , ( ctx - > config . hash_size * sizeof ( THashHashRow ) ) ) ;
/* pre allocate prealloc */
for ( i = 0 ; i < ctx - > config . prealloc ; i + + ) {
@ -281,7 +288,7 @@ static int THashInitConfig(THashTableContext *ctx, const char *cnf_prefix)
return - 1 ;
}
THashData * h = THashDataAlloc ( ctx );
THashData * h = THashDataAlloc ( ctx , 0 /* as we don't have string data here */ );
if ( h = = NULL ) {
SCLogError ( " preallocating data failed: %s " , strerror ( errno ) ) ;
return - 1 ;
@ -374,6 +381,7 @@ void THashShutdown(THashTableContext *ctx)
}
( void ) SC_ATOMIC_SUB ( ctx - > memuse , ctx - > config . hash_size * sizeof ( THashHashRow ) ) ;
THashDataQueueDestroy ( & ctx - > spare_q ) ;
DEBUG_VALIDATE_BUG_ON ( SC_ATOMIC_GET ( ctx - > memuse ) ! = 0 ) ;
SCFree ( ctx ) ;
}
@ -447,6 +455,11 @@ uint32_t THashExpire(THashTableContext *ctx, const SCTime_t ts)
h - > next = NULL ;
h - > prev = NULL ;
SCLogDebug ( " timeout: removing data %p " , h ) ;
if ( ctx - > config . DataSize ) {
uint32_t data_size = ctx - > config . DataSize ( h - > data ) ;
if ( data_size > 0 )
( void ) SC_ATOMIC_SUB ( ctx - > memuse , ( uint64_t ) data_size ) ;
}
ctx - > config . DataFree ( h - > data ) ;
THashDataUnlock ( h ) ;
THashDataMoveToSpare ( ctx , h ) ;
@ -495,6 +508,11 @@ void THashCleanup(THashTableContext *ctx)
hb - > tail = h - > prev ;
h - > next = NULL ;
h - > prev = NULL ;
if ( ctx - > config . DataSize ) {
uint32_t data_size = ctx - > config . DataSize ( h - > data ) ;
if ( data_size > 0 )
( void ) SC_ATOMIC_SUB ( ctx - > memuse , ( uint64_t ) data_size ) ;
}
THashDataMoveToSpare ( ctx , h ) ;
h = n ;
}
@ -537,13 +555,17 @@ static inline int THashCompare(const THashConfig *cnf, void *a, void *b)
static THashData * THashDataGetNew ( THashTableContext * ctx , void * data )
{
THashData * h = NULL ;
uint32_t data_size = 0 ;
if ( ctx - > config . DataSize ) {
data_size = ctx - > config . DataSize ( data ) ;
}
/* get data from the spare queue */
h = THashDataDequeue ( & ctx - > spare_q ) ;
if ( h = = NULL ) {
/* If we reached the max memcap, we get used data */
if ( ! ( THASH_CHECK_MEMCAP ( ctx , THASH_DATA_SIZE ( ctx ) ) ) ) {
h = THashGetUsed ( ctx );
if ( ! ( THASH_CHECK_MEMCAP ( ctx , THASH_DATA_SIZE ( ctx ) + data_size ) ) ) {
h = THashGetUsed ( ctx , data_size );
if ( h = = NULL ) {
return NULL ;
}
@ -555,7 +577,7 @@ static THashData *THashDataGetNew(THashTableContext *ctx, void *data)
/* freed data, but it's unlocked */
} else {
/* now see if we can alloc a new data */
h = THashDataAlloc ( ctx );
h = THashDataAlloc ( ctx , data_size );
if ( h = = NULL ) {
return NULL ;
}
@ -564,13 +586,24 @@ static THashData *THashDataGetNew(THashTableContext *ctx, void *data)
}
} else {
/* data has been recycled before it went into the spare queue */
/* data is initialized (recycled) but *unlocked* */
/* the recycled data was THashData and again does not include
* the size of current data to be added */
if ( data_size > 0 ) {
/* Since it is prealloc'd data, it already has THashData in its memuse */
( void ) SC_ATOMIC_ADD ( ctx - > memuse , data_size ) ;
if ( ! ( THASH_CHECK_MEMCAP ( ctx , data_size ) ) ) {
if ( ! SC_ATOMIC_GET ( ctx - > memcap_reached ) ) {
SC_ATOMIC_SET ( ctx - > memcap_reached , true ) ;
}
SCLogError ( " Adding data will exceed memcap: % " PRIu64 " , current memuse: % " PRIu64 ,
( ctx ) - > config . memcap , SC_ATOMIC_GET ( ctx - > memuse ) ) ;
}
}
}
// setup the data
BUG_ON ( ctx - > config . DataSet ( h - > data , data ) ! = 0 ) ;
( void ) SC_ATOMIC_ADD ( ctx - > counter , 1 ) ;
SCMutexLock ( & h - > m ) ;
return h ;
@ -765,7 +798,7 @@ THashData *THashLookupFromHash (THashTableContext *ctx, void *data)
*
* \ retval h data or NULL
*/
static THashData * THashGetUsed ( THashTableContext * ctx )
static THashData * THashGetUsed ( THashTableContext * ctx , uint32_t data_size )
{
uint32_t idx = SC_ATOMIC_GET ( ctx - > prune_idx ) % ctx - > config . hash_size ;
uint32_t cnt = ctx - > config . hash_size ;
@ -811,11 +844,19 @@ static THashData *THashGetUsed(THashTableContext *ctx)
HRLOCK_UNLOCK ( hb ) ;
if ( h - > data ! = NULL ) {
if ( ctx - > config . DataSize ) {
uint32_t h_data_size = ctx - > config . DataSize ( h - > data ) ;
if ( h_data_size > 0 ) {
( void ) SC_ATOMIC_SUB ( ctx - > memuse , ( uint64_t ) h_data_size ) ;
}
}
ctx - > config . DataFree ( h - > data ) ;
}
SCMutexUnlock ( & h - > m ) ;
( void ) SC_ATOMIC_ADD ( ctx - > prune_idx , ( ctx - > config . hash_size - cnt ) ) ;
if ( data_size > 0 )
( void ) SC_ATOMIC_ADD ( ctx - > memuse , data_size ) ;
return h ;
}