From: Jaroslav Kysela Date: Wed, 10 Jan 2018 13:26:25 +0000 (+0100) Subject: htsmsg: next round of optimization - reduce htsmsg_field_t size X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d35359fd828ea4011a6ae22e723269d2b04b8b31;p=thirdparty%2Ftvheadend.git htsmsg: next round of optimization - reduce htsmsg_field_t size The hmf_name and hmf_msg fields were shuffled to save more than 40% of memory space. --- diff --git a/src/htsmsg.c b/src/htsmsg.c index 41b7b6f37..7924bd68f 100644 --- a/src/htsmsg.c +++ b/src/htsmsg.c @@ -46,7 +46,13 @@ htsmsg_field_data_destroy(htsmsg_field_t *f) switch(f->hmf_type) { case HMF_MAP: case HMF_LIST: - htsmsg_clear(&f->hmf_msg); + htsmsg_clear(f->hmf_msg); + if(f->hmf_flags & HMF_ALLOCED) { +#if ENABLE_SLOW_MEMORYINFO + memoryinfo_remove(&htsmsg_field_memoryinfo, sizeof(htsmsg_t)); +#endif + free(f->hmf_msg); + } break; case HMF_STR: @@ -111,32 +117,33 @@ htsmsg_field_add(htsmsg_t *msg, const char *name, int type, int flags, size_t es size_t nsize; htsmsg_field_t *f; - nsize = name ? strlen(name) + 1 : 0; + nsize = name ? strlen(name) + 1 : 1; f = malloc(sizeof(htsmsg_field_t) + nsize + esize); if(f == NULL) return NULL; TAILQ_INSERT_TAIL(&msg->hm_fields, f, hmf_link); if(msg->hm_islist) { - assert(name == NULL); + assert(name == NULL || *name == '\0'); } else { - assert(name != NULL); + assert(name != NULL && *name); } if (name) { - f->hmf_name = f->hmf_edata; - strcpy(f->hmf_edata, name); + strcpy((char *)f->hmf_name, name); } else { - f->hmf_name = NULL; + ((char *)f->hmf_name)[0] = '\0'; } if(esize) { - if(type == HMF_STR) - f->hmf_str = f->hmf_edata + nsize; - else if(type == HMF_UUID) - f->hmf_uuid = (uint8_t *)f->hmf_edata + nsize; - else if(type == HMF_BIN) { - f->hmf_bin = f->hmf_edata + nsize; + if(type == HMF_STR) { + f->hmf_str = f->hmf_name + nsize; + } else if(type == HMF_UUID) { + f->hmf_uuid = (uint8_t *)f->hmf_name + nsize; + } else if(type == HMF_LIST || type == HMF_MAP) { + f->hmf_msg = (htsmsg_t *)(f->hmf_name + nsize); + } else if(type == HMF_BIN) { + f->hmf_bin = f->hmf_name + nsize; f->hmf_binsize = esize; } } @@ -580,18 +587,20 @@ htsmsg_add_uuid(htsmsg_t *msg, const char *name, tvh_uuid_t *u) static htsmsg_t * htsmsg_field_set_msg(htsmsg_field_t *f, htsmsg_t *sub) { + htsmsg_t *m = f->hmf_msg; assert(sub->hm_data == NULL); - f->hmf_msg.hm_data = NULL; - f->hmf_msg.hm_data_size = 0; - f->hmf_msg.hm_islist = sub->hm_islist; - TAILQ_MOVE(&f->hmf_msg.hm_fields, &sub->hm_fields, hmf_link); + assert(f->hmf_type == HMF_LIST || f->hmf_type == HMF_MAP); + m->hm_data = NULL; + m->hm_data_size = 0; + m->hm_islist = sub->hm_islist; + TAILQ_MOVE(&m->hm_fields, &sub->hm_fields, hmf_link); #if ENABLE_SLOW_MEMORYINFO memoryinfo_free(&htsmsg_memoryinfo, sizeof(htsmsg_t)); #endif - free(sub); + htsmsg_destroy(sub); - if (f->hmf_type == (f->hmf_msg.hm_islist ? HMF_LIST : HMF_MAP)) - return &f->hmf_msg; + if (f->hmf_type == (m->hm_islist ? HMF_LIST : HMF_MAP)) + return m; return NULL; } @@ -604,7 +613,8 @@ htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub) { htsmsg_field_t *f; - f = htsmsg_field_add(msg, name, sub->hm_islist ? HMF_LIST : HMF_MAP, 0, 0); + f = htsmsg_field_add(msg, name, sub->hm_islist ? HMF_LIST : HMF_MAP, + 0, sizeof(htsmsg_t)); return htsmsg_field_set_msg(f, sub); } @@ -621,31 +631,30 @@ htsmsg_set_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub) return htsmsg_field_set_msg(f, sub); } - - /* * */ void htsmsg_add_msg_extname(htsmsg_t *msg, const char *name, htsmsg_t *sub) { + htsmsg_t *m; htsmsg_field_t *f; - f = htsmsg_field_add(msg, name, sub->hm_islist ? HMF_LIST : HMF_MAP, 0, 0); + f = htsmsg_field_add(msg, name, sub->hm_islist ? HMF_LIST : HMF_MAP, + 0, sizeof(htsmsg_t)); + m = f->hmf_msg; assert(sub->hm_data == NULL); - f->hmf_msg.hm_data = NULL; - f->hmf_msg.hm_data_size = 0; - TAILQ_MOVE(&f->hmf_msg.hm_fields, &sub->hm_fields, hmf_link); - f->hmf_msg.hm_islist = sub->hm_islist; + m->hm_data = NULL; + m->hm_data_size = 0; + TAILQ_MOVE(&m->hm_fields, &sub->hm_fields, hmf_link); + m->hm_islist = sub->hm_islist; #if ENABLE_SLOW_MEMORYINFO memoryinfo_free(&htsmsg_memoryinfo, sizeof(htsmsg_t)); #endif - free(sub); + htsmsg_destroy(sub); } - - /** * */ @@ -683,11 +692,9 @@ htsmsg_field_get_s64 return 0; } - /** * */ - int bool_check(const char *str) { @@ -739,7 +746,6 @@ htsmsg_get_bool_or_default(htsmsg_t *msg, const char *name, int def) return htsmsg_get_bool(msg, name, &ret) ? def : ret; } - /** * */ @@ -750,7 +756,6 @@ htsmsg_get_s64_or_default(htsmsg_t *msg, const char *name, int64_t def) return htsmsg_get_s64(msg, name, &s64) ? def : s64; } - /* * */ @@ -1060,7 +1065,7 @@ htsmsg_get_str_multi(htsmsg_t *msg, ...) r = f->hmf_str; break; } else if(f->hmf_type == HMF_MAP) - msg = &f->hmf_msg; + msg = f->hmf_msg; else break; } @@ -1094,7 +1099,7 @@ htsmsg_field_get_list ( htsmsg_field_t *f ) static htsmsg_t * htsmsg_field_get_msg ( htsmsg_field_t *f, int islist ) { - htsmsg_t *m; + htsmsg_t *m, *l; /* Deserialize JSON (will keep either list or map) */ if (f->hmf_type == HMF_STR) { @@ -1105,20 +1110,22 @@ htsmsg_field_get_msg ( htsmsg_field_t *f, int islist ) #endif free((void*)f->hmf_str); } - f->hmf_type = m->hm_islist ? HMF_LIST : HMF_MAP; - f->hmf_msg.hm_islist = m->hm_islist; - f->hmf_msg.hm_data = NULL; - f->hmf_msg.hm_data_size = 0; - TAILQ_MOVE(&f->hmf_msg.hm_fields, &m->hm_fields, hmf_link); + l = f->hmf_msg = malloc(sizeof(htsmsg_t)); + f->hmf_type = m->hm_islist ? HMF_LIST : HMF_MAP; + f->hmf_flags |= HMF_ALLOCED; + l->hm_islist = m->hm_islist; + l->hm_data = NULL; + l->hm_data_size = 0; + TAILQ_MOVE(&l->hm_fields, &m->hm_fields, hmf_link); #if ENABLE_SLOW_MEMORYINFO memoryinfo_free(&htsmsg_memoryinfo, sizeof(htsmsg_t)); #endif - free(m); + htsmsg_destroy(m); } } if (f->hmf_type == (islist ? HMF_LIST : HMF_MAP)) - return &f->hmf_msg; + return f->hmf_msg; return NULL; } @@ -1129,10 +1136,10 @@ htsmsg_field_get_msg ( htsmsg_field_t *f, int islist ) htsmsg_t * htsmsg_detach_submsg(htsmsg_field_t *f) { + htsmsg_t *m = f->hmf_msg; htsmsg_t *r = htsmsg_create_map(); - TAILQ_MOVE(&r->hm_fields, &f->hmf_msg.hm_fields, hmf_link); - TAILQ_INIT(&f->hmf_msg.hm_fields); + TAILQ_MOVE(&r->hm_fields, &m->hm_fields, hmf_link); r->hm_islist = f->hmf_type == HMF_LIST; return r; } @@ -1157,14 +1164,14 @@ htsmsg_print0(htsmsg_t *msg, int indent) case HMF_MAP: printf("MAP) = {\n"); - htsmsg_print0(&f->hmf_msg, indent + 1); + htsmsg_print0(f->hmf_msg, indent + 1); for(i = 0; i < indent; i++) printf("\t"); printf("}\n"); break; case HMF_LIST: printf("LIST) = {\n"); - htsmsg_print0(&f->hmf_msg, indent + 1); + htsmsg_print0(f->hmf_msg, indent + 1); for(i = 0; i < indent; i++) printf("\t"); printf("}\n"); break; @@ -1222,7 +1229,7 @@ htsmsg_copy_i(const htsmsg_t *src, htsmsg_t *dst) case HMF_LIST: sub = f->hmf_type == HMF_LIST ? htsmsg_create_list() : htsmsg_create_map(); - htsmsg_copy_i(&f->hmf_msg, sub); + htsmsg_copy_i(f->hmf_msg, sub); htsmsg_add_msg(dst, f->hmf_name, sub); break; @@ -1287,7 +1294,7 @@ htsmsg_cmp(const htsmsg_t *m1, const htsmsg_t *m2) case HMF_MAP: case HMF_LIST: - if (htsmsg_cmp(&f1->hmf_msg, &f2->hmf_msg)) + if (htsmsg_cmp(f1->hmf_msg, f2->hmf_msg)) return 1; break; @@ -1353,7 +1360,7 @@ htsmsg_get_map_by_field_if_name(htsmsg_field_t *f, const char *name) return NULL; if(strcmp(f->hmf_name, name)) return NULL; - return &f->hmf_msg; + return f->hmf_msg; } diff --git a/src/htsmsg.h b/src/htsmsg.h index cf6af603e..6ff6dc299 100644 --- a/src/htsmsg.h +++ b/src/htsmsg.h @@ -58,7 +58,6 @@ typedef struct htsmsg { typedef struct htsmsg_field { TAILQ_ENTRY(htsmsg_field) hmf_link; - const char *hmf_name; uint8_t hmf_type; uint8_t hmf_flags; @@ -73,7 +72,7 @@ typedef struct htsmsg_field { const char *data; size_t len; } bin; - htsmsg_t msg; + htsmsg_t *msg; double dbl; int bool; } u; @@ -81,7 +80,7 @@ typedef struct htsmsg_field { #if ENABLE_SLOW_MEMORYINFO size_t hmf_edata_size; #endif - char hmf_edata[0]; + const char hmf_name[0]; } htsmsg_field_t; #define hmf_s64 u.s64 diff --git a/src/htsmsg_binary.c b/src/htsmsg_binary.c index 4cfef0ec6..91da0cdbd 100644 --- a/src/htsmsg_binary.c +++ b/src/htsmsg_binary.c @@ -54,10 +54,12 @@ htsmsg_binary_des0(htsmsg_t *msg, const uint8_t *buf, size_t len) if(len < namelen + datalen) return -1; - nlen = namelen ? namelen + 1 : 0; + nlen = namelen ? namelen + 1 : 1; tlen = sizeof(htsmsg_field_t) + nlen; if (type == HMF_STR) { tlen += datalen + 1; + } else if (type == HMF_LIST || type == HMF_MAP) { + tlen += sizeof(htsmsg_t); } else if (type == HMF_UUID) { tlen = UUID_BIN_SIZE; if (tlen != datalen) @@ -74,26 +76,25 @@ htsmsg_binary_des0(htsmsg_t *msg, const uint8_t *buf, size_t len) f->hmf_flags = 0; if(namelen > 0) { - f->hmf_name = f->hmf_edata; - memcpy(f->hmf_edata, buf, namelen); - f->hmf_edata[namelen] = 0; + memcpy((char *)f->hmf_name, buf, namelen); + ((char *)f->hmf_name)[namelen] = 0; buf += namelen; len -= namelen; } else { - f->hmf_name = NULL; + ((char *)f->hmf_name)[0] = '\0'; } switch(type) { case HMF_STR: - f->hmf_str = f->hmf_edata + nlen; + f->hmf_str = f->hmf_name + nlen; memcpy((char *)f->hmf_str, buf, datalen); ((char *)f->hmf_str)[datalen] = 0; f->hmf_flags |= HMF_INALLOCED; break; case HMF_UUID: - f->hmf_uuid = (uint8_t *)f->hmf_edata + nlen; + f->hmf_uuid = (uint8_t *)f->hmf_name + nlen; memcpy((char *)f->hmf_uuid, buf, UUID_BIN_SIZE); break; @@ -112,7 +113,7 @@ htsmsg_binary_des0(htsmsg_t *msg, const uint8_t *buf, size_t len) case HMF_MAP: case HMF_LIST: - sub = &f->hmf_msg; + sub = f->hmf_msg = (htsmsg_t *)(f->hmf_name + nlen); TAILQ_INIT(&sub->hm_fields); sub->hm_data = NULL; sub->hm_data_size = 0; @@ -225,7 +226,7 @@ htsmsg_binary_count(htsmsg_t *msg) switch(f->hmf_type) { case HMF_MAP: case HMF_LIST: - len += htsmsg_binary_count(&f->hmf_msg); + len += htsmsg_binary_count(f->hmf_msg); break; case HMF_STR: @@ -275,7 +276,7 @@ htsmsg_binary_write(htsmsg_t *msg, uint8_t *ptr) switch(f->hmf_type) { case HMF_MAP: case HMF_LIST: - l = htsmsg_binary_count(&f->hmf_msg); + l = htsmsg_binary_count(f->hmf_msg); break; case HMF_STR: @@ -317,7 +318,7 @@ htsmsg_binary_write(htsmsg_t *msg, uint8_t *ptr) switch(f->hmf_type) { case HMF_MAP: case HMF_LIST: - htsmsg_binary_write(&f->hmf_msg, ptr); + htsmsg_binary_write(f->hmf_msg, ptr); break; case HMF_STR: diff --git a/src/htsmsg_binary2.c b/src/htsmsg_binary2.c index 3f0c44055..7c4c9b9ad 100644 --- a/src/htsmsg_binary2.c +++ b/src/htsmsg_binary2.c @@ -114,10 +114,12 @@ htsmsg_binary2_des0(htsmsg_t *msg, const uint8_t *buf, uint32_t len) if(len < namelen + datalen) abort(); // return -1; - nlen = namelen ? namelen + 1 : 0; + nlen = namelen ? namelen + 1 : 1; tlen = sizeof(htsmsg_field_t) + nlen; if (type == HMF_STR) { - tlen += datalen ? datalen + 1 : 0; + tlen += datalen + 1; + } else if (type == HMF_LIST || type == HMF_MAP) { + tlen += sizeof(htsmsg_t); } else if (type == HMF_UUID) { tlen += UUID_BIN_SIZE; if (datalen != UUID_BIN_SIZE) @@ -134,26 +136,25 @@ htsmsg_binary2_des0(htsmsg_t *msg, const uint8_t *buf, uint32_t len) f->hmf_flags = 0; if(namelen > 0) { - f->hmf_name = f->hmf_edata; - memcpy(f->hmf_edata, buf, namelen); - f->hmf_edata[namelen] = 0; + memcpy((char *)f->hmf_name, buf, namelen); + ((char *)f->hmf_name)[namelen] = 0; buf += namelen; len -= namelen; } else { - f->hmf_name = NULL; + ((char *)f->hmf_name)[0] = '\0'; } switch(type) { case HMF_STR: - f->hmf_str = f->hmf_edata + nlen; + f->hmf_str = f->hmf_name + nlen; memcpy((char *)f->hmf_str, buf, datalen); ((char *)f->hmf_str)[datalen] = 0; f->hmf_flags |= HMF_INALLOCED; break; case HMF_UUID: - f->hmf_uuid = (uint8_t *)f->hmf_edata + nlen; + f->hmf_uuid = (uint8_t *)f->hmf_name + nlen; memcpy((char *)f->hmf_uuid, buf, UUID_BIN_SIZE); break; @@ -172,7 +173,7 @@ htsmsg_binary2_des0(htsmsg_t *msg, const uint8_t *buf, uint32_t len) case HMF_MAP: case HMF_LIST: - sub = &f->hmf_msg; + sub = f->hmf_msg = (htsmsg_t *)(f->hmf_name + nlen); TAILQ_INIT(&sub->hm_fields); sub->hm_data = NULL; sub->hm_data_size = 0; @@ -286,7 +287,7 @@ htsmsg_binary2_field_length(htsmsg_field_t *f) switch(f->hmf_type) { case HMF_MAP: case HMF_LIST: - return htsmsg_binary2_count(&f->hmf_msg); + return htsmsg_binary2_count(f->hmf_msg); case HMF_STR: return strlen(f->hmf_str); @@ -359,7 +360,7 @@ htsmsg_binary2_write(htsmsg_t *msg, uint8_t *ptr) switch(f->hmf_type) { case HMF_MAP: case HMF_LIST: - htsmsg_binary2_write(&f->hmf_msg, ptr); + htsmsg_binary2_write(f->hmf_msg, ptr); break; case HMF_STR: diff --git a/src/htsmsg_json.c b/src/htsmsg_json.c index b9b072c26..95ab23571 100644 --- a/src/htsmsg_json.c +++ b/src/htsmsg_json.c @@ -55,11 +55,11 @@ htsmsg_json_write(htsmsg_t *msg, htsbuf_queue_t *hq, int isarray, switch(f->hmf_type) { case HMF_MAP: - htsmsg_json_write(&f->hmf_msg, hq, 0, indent + 1, pretty); + htsmsg_json_write(f->hmf_msg, hq, 0, indent + 1, pretty); break; case HMF_LIST: - htsmsg_json_write(&f->hmf_msg, hq, 1, indent + 1, pretty); + htsmsg_json_write(f->hmf_msg, hq, 1, indent + 1, pretty); break; case HMF_STR: