From d562c8f32deb578e7c4c6ac0e9fa2cd6a367ca10 Mon Sep 17 00:00:00 2001 From: ruti <> Date: Tue, 17 Jun 2025 17:48:56 +0300 Subject: [PATCH] Move host without copying (#298) --- extend.c | 23 +++++++++++++---------- main.c | 4 ++-- mpool.c | 53 ++++++++++++++++++++++++++++------------------------- mpool.h | 28 +++++++++++++++++----------- 4 files changed, 60 insertions(+), 48 deletions(-) diff --git a/extend.c b/extend.c index 38c2561..0337378 100644 --- a/extend.c +++ b/extend.c @@ -68,7 +68,7 @@ static struct elem_i *cache_get(const union sockaddr_u *dst) struct cache_key key = { 0 }; int len = serialize_addr(dst, &key); - struct elem_i *val = (struct elem_i *)mem_get(params.mempool, (char *)&key, len); + struct elem_i *val = mem_get(params.mempool, (char *)&key, len); if (!val) { return 0; } @@ -83,29 +83,30 @@ static struct elem_i *cache_get(const union sockaddr_u *dst) static struct elem_i *cache_add( - const union sockaddr_u *dst, const char *host, int host_len) + const union sockaddr_u *dst, char **host, int host_len) { struct cache_key key = { 0 }; int cmp_len = serialize_addr(dst, &key); time_t t = time(0); - size_t total = sizeof(struct cache_data) + host_len; - struct cache_data *data = calloc(1, total); + struct cache_key *data = calloc(1, cmp_len); if (!data) { return 0; } memcpy(data, &key, cmp_len); - data->host_len = host_len; - memcpy(data->host, host, host_len); - - struct elem_i *val = (struct elem_i *)mem_add(params.mempool, (char *)data, cmp_len, sizeof(struct elem_i)); + struct elem_i *val = mem_add(params.mempool, (char *)data, cmp_len, sizeof(struct elem_i)); if (!val) { uniperror("mem_add"); free(data); return 0; } val->time = t; + if (!val->extra && *host) { + val->extra_len = host_len; + val->extra = *host; + *host = 0; + } return val; } @@ -276,6 +277,8 @@ static void swop_groups(struct desync_params *dpc, struct desync_params *dpn) if (dpc->fail_count <= dpn->fail_count) { return; } + LOG(LOG_S, "swop: %d <-> %d\n", dpc->id, dpn->id); + struct desync_params dpc_cp = *dpc; dpc->next = dpn->next; dpc->prev = dpn->prev; @@ -336,7 +339,7 @@ static int on_trigger(int type, struct poolhd *pool, struct eval *val) } LOG(LOG_S, "save: ip=%s, id=%d\n", ADDR_STR, dp->id); - struct elem_i *e = cache_add(&val->addr, val->pair->host, val->pair->host_len); + struct elem_i *e = cache_add(&val->addr, &val->pair->host, val->pair->host_len); if (e) { e->dp = dp; e->dp_mask = val->pair->dp_mask; @@ -348,7 +351,7 @@ static int on_trigger(int type, struct poolhd *pool, struct eval *val) } LOG(LOG_S, "unreach ip: %s\n", ADDR_STR); - struct elem_i *e = cache_add(&val->addr, val->pair->host, val->pair->host_len); + struct elem_i *e = cache_add(&val->addr, &val->pair->host, val->pair->host_len); if (e) { e->dp = params.dp; e->dp_mask = 0; diff --git a/main.c b/main.c index dadeab3..4ec7a1b 100644 --- a/main.c +++ b/main.c @@ -309,7 +309,7 @@ static inline int lower_char(char *cl) struct mphdr *parse_hosts(char *buffer, size_t size) { - struct mphdr *hdr = mem_pool(1, CMP_HOST); + struct mphdr *hdr = mem_pool(MF_STATIC, CMP_HOST); if (!hdr) { return 0; } @@ -1201,7 +1201,7 @@ int main(int argc, char **argv) return -1; } } - params.mempool = mem_pool(0, CMP_BYTES); + params.mempool = mem_pool(MF_EXTRA, CMP_BYTES); if (!params.mempool) { uniperror("mem_pool"); clear_params(); diff --git a/mpool.c b/mpool.c index 2b7fffa..42638bc 100644 --- a/mpool.c +++ b/mpool.c @@ -67,18 +67,18 @@ static int scmp(const struct elem *p, const struct elem *q) KAVL_INIT(my, struct elem, head, scmp) -struct mphdr *mem_pool(bool is_static, unsigned char cmp_type) +struct mphdr *mem_pool(unsigned short flags, unsigned char cmp_type) { struct mphdr *hdr = calloc(1, sizeof(struct mphdr)); if (hdr) { - hdr->static_data = is_static; + hdr->flags = flags; hdr->cmp_type = cmp_type; } return hdr; } -struct elem *mem_get(const struct mphdr *hdr, const char *str, int len) +void *mem_get(const struct mphdr *hdr, const char *str, int len) { struct elem temp = { .cmp_type = hdr->cmp_type, @@ -88,7 +88,19 @@ struct elem *mem_get(const struct mphdr *hdr, const char *str, int len) } -struct elem *mem_add(struct mphdr *hdr, char *str, int len, size_t struct_size) +static void destroy_elem(struct mphdr *hdr, struct elem *e) +{ + if (!(hdr->flags & MF_STATIC)) { + free(e->data); + } + if (hdr->flags & MF_EXTRA) { + free(((struct elem_ex *)e)->extra); + } + free(e); +} + + +void *mem_add(struct mphdr *hdr, char *str, int len, size_t struct_size) { struct elem *v, *e = calloc(1, struct_size); if (!e) { @@ -104,9 +116,7 @@ struct elem *mem_add(struct mphdr *hdr, char *str, int len, size_t struct_size) v = kavl_insert(my, &hdr->root, e, 0); } if (e != v) { - if (!hdr->static_data) - free(e->data); - free(e); + destroy_elem(hdr, e); } else hdr->count++; return v; @@ -123,11 +133,7 @@ void mem_delete(struct mphdr *hdr, const char *str, int len) if (!e) { return; } - if (!hdr->static_data) { - free(e->data); - e->data = 0; - } - free(e); + destroy_elem(hdr, e); hdr->count--; } @@ -139,11 +145,7 @@ void mem_destroy(struct mphdr *hdr) if (!e) { break; } - if (!hdr->static_data) { - free(e->data); - } - e->data = 0; - free(e); + destroy_elem(hdr, e); } free(hdr); } @@ -157,17 +159,18 @@ void dump_cache(struct mphdr *hdr, FILE *out) kavl_itr_t(my) itr; kavl_itr_first(my, hdr->root, &itr); do { - const struct elem_i *p = (const struct elem_i *)kavl_at(&itr); - struct cache_data *value = (struct cache_data *)p->i.data; + struct elem_i *p = (struct elem_i *)kavl_at(&itr); + struct cache_key *key = (struct cache_key *)p->main.data; char ADDR_STR[INET6_ADDRSTRLEN]; - if (value->key.family == AF_INET) - inet_ntop(AF_INET, &value->key.ip.v4, ADDR_STR, sizeof(ADDR_STR)); + if (key->family == AF_INET) + inet_ntop(AF_INET, &key->ip.v4, ADDR_STR, sizeof(ADDR_STR)); else - inet_ntop(AF_INET6, &value->key.ip.v6, ADDR_STR, sizeof(ADDR_STR)); + inet_ntop(AF_INET6, &key->ip.v6, ADDR_STR, sizeof(ADDR_STR)); fprintf(out, "%s %d %d %jd %.*s\n", - ADDR_STR, ntohs(value->key.port), p->dp->id, - (intmax_t)p->time, value->host_len, value->host); - } while (kavl_itr_next(my, &itr)); + ADDR_STR, ntohs(key->port), p->dp->id, + (intmax_t)p->time, p->extra_len, p->extra ? p->extra : ""); + } + while (kavl_itr_next(my, &itr)); } diff --git a/mpool.h b/mpool.h index 89db85a..d9bfd2b 100644 --- a/mpool.h +++ b/mpool.h @@ -11,6 +11,9 @@ #define CMP_BITS 1 #define CMP_HOST 2 +#define MF_STATIC 1 +#define MF_EXTRA 2 + #pragma pack(push, 1) struct cache_key { @@ -22,12 +25,6 @@ struct cache_key { } ip; }; -struct cache_data { - struct cache_key key; - int host_len; - char host[]; -}; - #pragma pack(pop) struct elem { @@ -37,25 +34,34 @@ struct elem { KAVL_HEAD(struct elem) head; }; +struct elem_ex { + struct elem main; + unsigned int extra_len; + char *extra; +}; + struct elem_i { - struct elem i; + struct elem main; + unsigned int extra_len; + char *extra; + struct desync_params *dp; uint64_t dp_mask; time_t time; }; struct mphdr { - bool static_data; + unsigned short flags; unsigned char cmp_type; size_t count; struct elem *root; }; -struct mphdr *mem_pool(bool is_static, unsigned char cmp_type); +struct mphdr *mem_pool(unsigned short flags, unsigned char cmp_type); -struct elem *mem_get(const struct mphdr *hdr, const char *str, int len); +void *mem_get(const struct mphdr *hdr, const char *str, int len); -struct elem *mem_add(struct mphdr *hdr, char *str, int len, size_t ssize); +void *mem_add(struct mphdr *hdr, char *str, int len, size_t ssize); void mem_delete(struct mphdr *hdr, const char *str, int len);