[468987] Free unused topic elements.
Reduces memory usage and CPU usage. Thanks to Guido Hinderberger, Martin Rauscher and Michael Hekel. Bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=468987
This commit is contained in:
parent
13d869b8df
commit
ab7f212b7e
@ -5,6 +5,7 @@ Broker:
|
||||
autosave_interval=1. Closes #465438.
|
||||
- Fix handling of outgoing QoS>0 messages for bridges that could not be sent
|
||||
because the bridge connection was down.
|
||||
- Free unused topic tree elements. Closes #468987.
|
||||
|
||||
Client library:
|
||||
- Add missing error strings to mosquitto_strerror.
|
||||
|
@ -37,6 +37,7 @@ Fang Chong
|
||||
Frank Hansen
|
||||
Gary Koh
|
||||
Gianfranco Costamagna
|
||||
Guido Hinderberger
|
||||
Hiram van Paassen
|
||||
Jan-Piet Mens
|
||||
Joan Zapata
|
||||
@ -44,11 +45,13 @@ Joe McIlvain
|
||||
Karl Palsson
|
||||
Larry Lendo
|
||||
Martin Assarsson
|
||||
Martin Rauscher
|
||||
Martin van Wingerden
|
||||
Marty Lee
|
||||
Matt Daubney
|
||||
Michael C
|
||||
Michael Frisch
|
||||
Michael Hekel
|
||||
Michael Laing
|
||||
Michael Rushton
|
||||
Mike Bush
|
||||
|
@ -59,6 +59,7 @@ int mqtt3_db_open(struct mqtt3_config *config, struct mosquitto_db *db)
|
||||
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
|
||||
return MOSQ_ERR_NOMEM;
|
||||
}
|
||||
child->parent = NULL;
|
||||
child->next = NULL;
|
||||
child->topic = _mosquitto_strdup("");
|
||||
if(!child->topic){
|
||||
@ -75,6 +76,7 @@ int mqtt3_db_open(struct mqtt3_config *config, struct mosquitto_db *db)
|
||||
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
|
||||
return MOSQ_ERR_NOMEM;
|
||||
}
|
||||
child->parent = NULL;
|
||||
child->next = NULL;
|
||||
child->topic = _mosquitto_strdup("$SYS");
|
||||
if(!child->topic){
|
||||
|
@ -138,6 +138,7 @@ struct _mosquitto_subleaf {
|
||||
};
|
||||
|
||||
struct _mosquitto_subhier {
|
||||
struct _mosquitto_subhier *parent;
|
||||
struct _mosquitto_subhier *children;
|
||||
struct _mosquitto_subhier *next;
|
||||
struct _mosquitto_subleaf *subs;
|
||||
|
57
src/subs.c
57
src/subs.c
@ -327,6 +327,7 @@ static int _sub_add(struct mosquitto_db *db, struct mosquitto *context, int qos,
|
||||
/* Not found */
|
||||
branch = _mosquitto_calloc(1, sizeof(struct _mosquitto_subhier));
|
||||
if(!branch) return MOSQ_ERR_NOMEM;
|
||||
branch->parent = subhier;
|
||||
branch->topic = _mosquitto_strdup(tokens->topic);
|
||||
if(!branch->topic){
|
||||
_mosquitto_free(branch);
|
||||
@ -459,6 +460,7 @@ int mqtt3_sub_add(struct mosquitto_db *db, struct mosquitto *context, const char
|
||||
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
|
||||
return MOSQ_ERR_NOMEM;
|
||||
}
|
||||
child->parent = root;
|
||||
child->topic = _mosquitto_strdup(tokens->topic);
|
||||
if(!child->topic){
|
||||
_sub_topic_tokens_free(tokens);
|
||||
@ -548,12 +550,56 @@ int mqtt3_db_messages_queue(struct mosquitto_db *db, const char *source_id, cons
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Remove a subhier element, and return its parent if that needs freeing as well. */
|
||||
static struct _mosquitto_subhier *tmp_remove_subs(struct _mosquitto_subhier *sub)
|
||||
{
|
||||
struct _mosquitto_subhier *parent;
|
||||
struct _mosquitto_subhier *hier;
|
||||
struct _mosquitto_subhier *last = NULL;
|
||||
|
||||
if(!sub || !sub->parent){
|
||||
return NULL;
|
||||
}
|
||||
if(sub->children || sub->subs || sub->next){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parent = sub->parent;
|
||||
hier = sub->parent->children;
|
||||
while(hier){
|
||||
if(hier == sub){
|
||||
if(last){
|
||||
last->next = sub->next;
|
||||
}else{
|
||||
parent->children = NULL;
|
||||
}
|
||||
if(sub->topic) _mosquitto_free(sub->topic);
|
||||
_mosquitto_free(sub);
|
||||
break;
|
||||
}
|
||||
last = hier;
|
||||
hier = hier->next;
|
||||
}
|
||||
if(parent->subs == NULL
|
||||
&& parent->children == NULL
|
||||
&& parent->retained == NULL
|
||||
&& parent->parent){
|
||||
|
||||
return parent;
|
||||
}else{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Remove all subscriptions for a client.
|
||||
*/
|
||||
int mqtt3_subs_clean_session(struct mosquitto_db *db, struct mosquitto *context)
|
||||
{
|
||||
int i;
|
||||
struct _mosquitto_subleaf *leaf;
|
||||
struct _mosquitto_subhier *hier;
|
||||
|
||||
for(i=0; i<context->sub_count; i++){
|
||||
if(context->subs[i] == NULL){
|
||||
@ -578,6 +624,17 @@ int mqtt3_subs_clean_session(struct mosquitto_db *db, struct mosquitto *context)
|
||||
}
|
||||
leaf = leaf->next;
|
||||
}
|
||||
if(context->subs[i]->subs == NULL
|
||||
&& context->subs[i]->children == NULL
|
||||
&& context->subs[i]->retained == NULL
|
||||
&& context->subs[i]->parent){
|
||||
|
||||
hier = context->subs[i];
|
||||
context->subs[i] = NULL;
|
||||
do{
|
||||
hier = tmp_remove_subs(hier);
|
||||
}while(hier);
|
||||
}
|
||||
}
|
||||
_mosquitto_free(context->subs);
|
||||
context->subs = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user