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)
|
static MXS_FILTER* createInstance(const char* name, MXS_CONFIG_PARAMETER* params)
|
||||||
{
|
{
|
||||||
HINT_INSTANCE* my_instance;
|
return static_cast<MXS_FILTER*>(new (std::nothrow)HINT_INSTANCE);
|
||||||
|
|
||||||
if ((my_instance = static_cast<HINT_INSTANCE*>(MXS_CALLOC(1, sizeof(HINT_INSTANCE)))) != NULL)
|
|
||||||
{
|
|
||||||
my_instance->sessions = 0;
|
|
||||||
}
|
|
||||||
return (MXS_FILTER*)my_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)
|
static MXS_FILTER_SESSION* newSession(MXS_FILTER* instance, MXS_SESSION* session)
|
||||||
{
|
{
|
||||||
HINT_SESSION* my_session;
|
return static_cast<MXS_FILTER_SESSION*>(new (std::nothrow)HINT_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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)
|
static void closeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session)
|
||||||
{
|
{
|
||||||
HINT_SESSION* my_session = (HINT_SESSION*)session;
|
HINT_SESSION* my_session = (HINT_SESSION*)session;
|
||||||
NAMEDHINTS* named_hints;
|
|
||||||
HINTSTACK* hint_stack;
|
|
||||||
|
|
||||||
/** Free named hints */
|
for (auto& a : my_session->named_hints)
|
||||||
named_hints = my_session->named_hints;
|
|
||||||
|
|
||||||
while ((named_hints = free_named_hint(named_hints)) != NULL)
|
|
||||||
{
|
{
|
||||||
|
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)
|
static void freeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session)
|
||||||
{
|
{
|
||||||
MXS_FREE(session);
|
delete session;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,158 +43,6 @@ typedef enum
|
|||||||
TOK_END
|
TOK_END
|
||||||
} TOKEN_VALUE;
|
} 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
|
* 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)))
|
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)
|
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)
|
else if (t.type == TOK_STRING)
|
||||||
{
|
{
|
||||||
@ -521,29 +373,29 @@ HINT* process_comment(HINT_SESSION* session, InputIter it, InputIter end)
|
|||||||
if (hint)
|
if (hint)
|
||||||
{
|
{
|
||||||
// Preparation of a named 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)
|
else if (t.type == TOK_START)
|
||||||
{
|
{
|
||||||
if ((rval = process_definition(it, end)))
|
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
|
// New hint defined, push it on to the stack
|
||||||
create_named_hint(session, key.c_str(), rval);
|
session->named_hints[key] = hint_dup(rval);
|
||||||
hint_push(session, hint_dup(rval));
|
session->stack.push_back(hint_dup(rval));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (next_token(&it, end).type == TOK_END)
|
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
|
// We're starting an already define named hint
|
||||||
hint_push(session, hint_dup(hint));
|
session->stack.push_back(hint_dup(it->second));
|
||||||
rval = hint_dup(hint);
|
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();
|
buf.release();
|
||||||
|
@ -15,55 +15,22 @@
|
|||||||
#include <maxscale/ccdefs.hh>
|
#include <maxscale/ccdefs.hh>
|
||||||
#include <maxscale/hint.h>
|
#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
|
* The hint instance structure
|
||||||
*/
|
*/
|
||||||
typedef struct
|
struct HINT_INSTANCE: public MXS_FILTER
|
||||||
{
|
{
|
||||||
int sessions;
|
int sessions = 0;
|
||||||
} HINT_INSTANCE;
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A hint parser session structure
|
* A hint parser session structure
|
||||||
*/
|
*/
|
||||||
typedef struct
|
struct HINT_SESSION: public MXS_FILTER_SESSION
|
||||||
{
|
{
|
||||||
MXS_DOWNSTREAM down;
|
MXS_DOWNSTREAM down;
|
||||||
HINTSTACK* stack;
|
std::vector<HINT*> stack;
|
||||||
NAMEDHINTS* named_hints; /* The named hints defined in this session */
|
std::unordered_map<std::string, HINT*> named_hints;
|
||||||
} HINT_SESSION;
|
};
|
||||||
|
|
||||||
NAMEDHINTS* free_named_hint(NAMEDHINTS* named_hint);
|
|
||||||
HINTSTACK* free_hint_stack(HINTSTACK* hint_stack);
|
|
||||||
void process_hints(HINT_SESSION* session, GWBUF* buffer);
|
void process_hints(HINT_SESSION* session, GWBUF* buffer);
|
||||||
|
|
||||||
MXS_END_DECLS
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user