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:
parent
a6ab05b673
commit
f106864659
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user