MXS-2302: Use STL containers for hint storage

The named hints and the hint stack are now stored in STL containers.
This commit is contained in:
Markus Mäkelä 2019-02-18 11:00:53 +02:00
parent a6ab05b673
commit f106864659
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
3 changed files with 30 additions and 231 deletions

View File

@ -101,13 +101,7 @@ extern "C"
*/
static MXS_FILTER* createInstance(const char* name, MXS_CONFIG_PARAMETER* params)
{
HINT_INSTANCE* my_instance;
if ((my_instance = static_cast<HINT_INSTANCE*>(MXS_CALLOC(1, sizeof(HINT_INSTANCE)))) != NULL)
{
my_instance->sessions = 0;
}
return (MXS_FILTER*)my_instance;
return static_cast<MXS_FILTER*>(new (std::nothrow)HINT_INSTANCE);
}
/**
@ -119,15 +113,7 @@ static MXS_FILTER* createInstance(const char* name, MXS_CONFIG_PARAMETER* params
*/
static MXS_FILTER_SESSION* newSession(MXS_FILTER* instance, MXS_SESSION* session)
{
HINT_SESSION* my_session;
if ((my_session = static_cast<HINT_SESSION*>(MXS_CALLOC(1, sizeof(HINT_SESSION)))) != NULL)
{
my_session->stack = NULL;
my_session->named_hints = NULL;
}
return (MXS_FILTER_SESSION*)my_session;
return static_cast<MXS_FILTER_SESSION*>(new (std::nothrow)HINT_SESSION);
}
/**
@ -140,20 +126,15 @@ static MXS_FILTER_SESSION* newSession(MXS_FILTER* instance, MXS_SESSION* session
static void closeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session)
{
HINT_SESSION* my_session = (HINT_SESSION*)session;
NAMEDHINTS* named_hints;
HINTSTACK* hint_stack;
/** Free named hints */
named_hints = my_session->named_hints;
while ((named_hints = free_named_hint(named_hints)) != NULL)
for (auto& a : my_session->named_hints)
{
hint_free(a.second);
}
/** Free stacked hints */
hint_stack = my_session->stack;
while ((hint_stack = free_hint_stack(hint_stack)) != NULL)
for (auto& a : my_session->stack)
{
hint_free(a);
}
}
@ -165,8 +146,7 @@ static void closeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session)
*/
static void freeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session)
{
MXS_FREE(session);
return;
delete session;
}
/**

View File

@ -43,158 +43,6 @@ typedef enum
TOK_END
} TOKEN_VALUE;
/**
* hint_pop - pop the hint off the top of the stack if it is not empty
*
* @param session The filter session.
*/
void hint_pop(HINT_SESSION* session)
{
HINTSTACK* ptr;
HINT* hint;
if ((ptr = session->stack) != NULL)
{
session->stack = ptr->next;
while (ptr->hint)
{
hint = ptr->hint;
ptr->hint = hint->next;
hint_free(hint);
}
MXS_FREE(ptr);
}
}
/**
* Push a hint onto the stack of actie hints
*
* @param session The filter session
* @param hint The hint to push, the hint ownership is retained
* by the stack and should not be freed by the caller
*/
static void hint_push(HINT_SESSION* session, HINT* hint)
{
HINTSTACK* item;
if ((item = (HINTSTACK*)MXS_MALLOC(sizeof(HINTSTACK))) == NULL)
{
return;
}
item->hint = hint;
item->next = session->stack;
session->stack = item;
}
/**
* Search for a hint block that already exists with this name
*
* @param session The filter session
* @param name The name to lookup
* @return the HINT or NULL if the name was not found.
*/
static HINT* lookup_named_hint(HINT_SESSION* session, const char* name)
{
NAMEDHINTS* ptr = session->named_hints;
while (ptr)
{
if (strcmp(ptr->name, name) == 0)
{
return ptr->hints;
}
ptr = ptr->next;
}
return NULL;
}
/**
* Create a named hint block
*
* @param session The filter session
* @param name The name of the block to ceate
* @param hint The hints themselves
*/
static void create_named_hint(HINT_SESSION* session, const char* name, HINT* hint)
{
NAMEDHINTS* block;
if ((block = (NAMEDHINTS*)MXS_MALLOC(sizeof(NAMEDHINTS))) == NULL)
{
return;
}
block->name = MXS_STRDUP(name);
block->hints = hint_dup(hint);
block->next = session->named_hints;
session->named_hints = block;
}
/**
* Release the given NAMEDHINTS struct and all included hints.
*
* @param named_hint NAMEDHINTS struct to be released
*
* @return pointer to next NAMEDHINTS struct.
*/
NAMEDHINTS* free_named_hint(NAMEDHINTS* named_hint)
{
NAMEDHINTS* next;
if (named_hint != NULL)
{
HINT* hint;
next = named_hint->next;
while (named_hint->hints != NULL)
{
hint = named_hint->hints->next;
hint_free(named_hint->hints);
named_hint->hints = hint;
}
MXS_FREE(named_hint->name);
MXS_FREE(named_hint);
return next;
}
else
{
return NULL;
}
}
/**
* Release the given HINTSTACK struct and all included hints.
*
* @param hint_stack HINTSTACK struct to be released
*
* @return pointer to next HINTSTACK struct.
*/
HINTSTACK* free_hint_stack(HINTSTACK* hint_stack)
{
HINTSTACK* next;
if (hint_stack != NULL)
{
HINT* hint;
next = hint_stack->next;
while (hint_stack->hint != NULL)
{
hint = hint_stack->hint->next;
hint_free(hint_stack->hint);
hint_stack->hint = hint;
}
MXS_FREE(hint_stack);
return next;
}
else
{
return NULL;
}
}
/**
* Advance an iterator until either an unescaped character `c` is found or `end` is reached
*
@ -491,12 +339,16 @@ HINT* process_comment(HINT_SESSION* session, InputIter it, InputIter end)
{
if ((rval = process_definition(it, end)))
{
hint_push(session, hint_dup(rval));
session->stack.push_back(hint_dup(rval));
}
}
else if (t.type == TOK_STOP)
{
hint_pop(session);
if (!session->stack.empty())
{
hint_free(session->stack.back());
session->stack.pop_back();
}
}
else if (t.type == TOK_STRING)
{
@ -521,29 +373,29 @@ HINT* process_comment(HINT_SESSION* session, InputIter it, InputIter end)
if (hint)
{
// Preparation of a named hint
create_named_hint(session, key.c_str(), hint);
session->named_hints[key] = hint_dup(hint);
}
}
else if (t.type == TOK_START)
{
if ((rval = process_definition(it, end)))
{
if (!lookup_named_hint(session, key.c_str()))
if (session->named_hints.count(key) == 0)
{
// New hint defined, push it on to the stack
create_named_hint(session, key.c_str(), rval);
hint_push(session, hint_dup(rval));
session->named_hints[key] = hint_dup(rval);
session->stack.push_back(hint_dup(rval));
}
}
else if (next_token(&it, end).type == TOK_END)
{
HINT* hint = lookup_named_hint(session, key.c_str());
auto it = session->named_hints.find(key);
if (hint)
if (it != session->named_hints.end())
{
// We're starting an already define named hint
hint_push(session, hint_dup(hint));
rval = hint_dup(hint);
session->stack.push_back(hint_dup(it->second));
rval = hint_dup(it->second);
}
}
}
@ -572,9 +424,9 @@ void process_hints(HINT_SESSION* session, GWBUF* buffer)
}
}
if (!buffer->hint && session->stack)
if (!buffer->hint && !session->stack.empty())
{
buffer->hint = hint_dup(session->stack->hint);
buffer->hint = hint_dup(session->stack.back());
}
buf.release();

View File

@ -15,55 +15,22 @@
#include <maxscale/ccdefs.hh>
#include <maxscale/hint.h>
MXS_BEGIN_DECLS
/**
* A named hint set.
*
* The hint "MaxScale name PREPARE ..." can be used to defined a named set
* of hints that can be later applied.
*/
typedef struct namedhints
{
char* name; /*< Hintsets name */
HINT* hints;
struct namedhints
* next; /*< Next named hint */
} NAMEDHINTS;
/**
* A session meaintains a stack of hints, the hints BEGIN and STOP are used
* push hints on and off the stack. The current top of the stack is added to
* any statement that does not explicitly define a hint for that signle
* statement.
*/
typedef struct hintstack
{
HINT* hint;
struct hintstack
* next;
} HINTSTACK;
/**
* The hint instance structure
*/
typedef struct
struct HINT_INSTANCE: public MXS_FILTER
{
int sessions;
} HINT_INSTANCE;
int sessions = 0;
};
/**
* A hint parser session structure
*/
typedef struct
struct HINT_SESSION: public MXS_FILTER_SESSION
{
MXS_DOWNSTREAM down;
HINTSTACK* stack;
NAMEDHINTS* named_hints; /* The named hints defined in this session */
} HINT_SESSION;
std::vector<HINT*> stack;
std::unordered_map<std::string, HINT*> named_hints;
};
NAMEDHINTS* free_named_hint(NAMEDHINTS* named_hint);
HINTSTACK* free_hint_stack(HINTSTACK* hint_stack);
void process_hints(HINT_SESSION* session, GWBUF* buffer);
MXS_END_DECLS