0
0
mirror of https://github.com/hufrea/byedpi.git synced 2025-06-29 18:21:14 +00:00

Move host without copying

(#298)
This commit is contained in:
ruti 2025-06-17 17:48:56 +03:00
parent b84f27b92a
commit d562c8f32d
4 changed files with 60 additions and 48 deletions

View File

@ -68,7 +68,7 @@ static struct elem_i *cache_get(const union sockaddr_u *dst)
struct cache_key key = { 0 }; struct cache_key key = { 0 };
int len = serialize_addr(dst, &key); 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) { if (!val) {
return 0; return 0;
} }
@ -83,29 +83,30 @@ static struct elem_i *cache_get(const union sockaddr_u *dst)
static struct elem_i *cache_add( 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 }; struct cache_key key = { 0 };
int cmp_len = serialize_addr(dst, &key); int cmp_len = serialize_addr(dst, &key);
time_t t = time(0); time_t t = time(0);
size_t total = sizeof(struct cache_data) + host_len; struct cache_key *data = calloc(1, cmp_len);
struct cache_data *data = calloc(1, total);
if (!data) { if (!data) {
return 0; return 0;
} }
memcpy(data, &key, cmp_len); memcpy(data, &key, cmp_len);
data->host_len = host_len; struct elem_i *val = mem_add(params.mempool, (char *)data, cmp_len, sizeof(struct elem_i));
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));
if (!val) { if (!val) {
uniperror("mem_add"); uniperror("mem_add");
free(data); free(data);
return 0; return 0;
} }
val->time = t; val->time = t;
if (!val->extra && *host) {
val->extra_len = host_len;
val->extra = *host;
*host = 0;
}
return val; 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) { if (dpc->fail_count <= dpn->fail_count) {
return; return;
} }
LOG(LOG_S, "swop: %d <-> %d\n", dpc->id, dpn->id);
struct desync_params dpc_cp = *dpc; struct desync_params dpc_cp = *dpc;
dpc->next = dpn->next; dpc->next = dpn->next;
dpc->prev = dpn->prev; 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); 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) { if (e) {
e->dp = dp; e->dp = dp;
e->dp_mask = val->pair->dp_mask; 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); 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) { if (e) {
e->dp = params.dp; e->dp = params.dp;
e->dp_mask = 0; e->dp_mask = 0;

4
main.c
View File

@ -309,7 +309,7 @@ static inline int lower_char(char *cl)
struct mphdr *parse_hosts(char *buffer, size_t size) 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) { if (!hdr) {
return 0; return 0;
} }
@ -1201,7 +1201,7 @@ int main(int argc, char **argv)
return -1; return -1;
} }
} }
params.mempool = mem_pool(0, CMP_BYTES); params.mempool = mem_pool(MF_EXTRA, CMP_BYTES);
if (!params.mempool) { if (!params.mempool) {
uniperror("mem_pool"); uniperror("mem_pool");
clear_params(); clear_params();

53
mpool.c
View File

@ -67,18 +67,18 @@ static int scmp(const struct elem *p, const struct elem *q)
KAVL_INIT(my, struct elem, head, scmp) 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)); struct mphdr *hdr = calloc(1, sizeof(struct mphdr));
if (hdr) { if (hdr) {
hdr->static_data = is_static; hdr->flags = flags;
hdr->cmp_type = cmp_type; hdr->cmp_type = cmp_type;
} }
return hdr; 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 = { struct elem temp = {
.cmp_type = hdr->cmp_type, .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); struct elem *v, *e = calloc(1, struct_size);
if (!e) { 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); v = kavl_insert(my, &hdr->root, e, 0);
} }
if (e != v) { if (e != v) {
if (!hdr->static_data) destroy_elem(hdr, e);
free(e->data);
free(e);
} }
else hdr->count++; else hdr->count++;
return v; return v;
@ -123,11 +133,7 @@ void mem_delete(struct mphdr *hdr, const char *str, int len)
if (!e) { if (!e) {
return; return;
} }
if (!hdr->static_data) { destroy_elem(hdr, e);
free(e->data);
e->data = 0;
}
free(e);
hdr->count--; hdr->count--;
} }
@ -139,11 +145,7 @@ void mem_destroy(struct mphdr *hdr)
if (!e) { if (!e) {
break; break;
} }
if (!hdr->static_data) { destroy_elem(hdr, e);
free(e->data);
}
e->data = 0;
free(e);
} }
free(hdr); free(hdr);
} }
@ -157,17 +159,18 @@ void dump_cache(struct mphdr *hdr, FILE *out)
kavl_itr_t(my) itr; kavl_itr_t(my) itr;
kavl_itr_first(my, hdr->root, &itr); kavl_itr_first(my, hdr->root, &itr);
do { do {
const struct elem_i *p = (const struct elem_i *)kavl_at(&itr); struct elem_i *p = (struct elem_i *)kavl_at(&itr);
struct cache_data *value = (struct cache_data *)p->i.data; struct cache_key *key = (struct cache_key *)p->main.data;
char ADDR_STR[INET6_ADDRSTRLEN]; char ADDR_STR[INET6_ADDRSTRLEN];
if (value->key.family == AF_INET) if (key->family == AF_INET)
inet_ntop(AF_INET, &value->key.ip.v4, ADDR_STR, sizeof(ADDR_STR)); inet_ntop(AF_INET, &key->ip.v4, ADDR_STR, sizeof(ADDR_STR));
else 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", fprintf(out, "%s %d %d %jd %.*s\n",
ADDR_STR, ntohs(value->key.port), p->dp->id, ADDR_STR, ntohs(key->port), p->dp->id,
(intmax_t)p->time, value->host_len, value->host); (intmax_t)p->time, p->extra_len, p->extra ? p->extra : "");
} while (kavl_itr_next(my, &itr)); }
while (kavl_itr_next(my, &itr));
} }

28
mpool.h
View File

@ -11,6 +11,9 @@
#define CMP_BITS 1 #define CMP_BITS 1
#define CMP_HOST 2 #define CMP_HOST 2
#define MF_STATIC 1
#define MF_EXTRA 2
#pragma pack(push, 1) #pragma pack(push, 1)
struct cache_key { struct cache_key {
@ -22,12 +25,6 @@ struct cache_key {
} ip; } ip;
}; };
struct cache_data {
struct cache_key key;
int host_len;
char host[];
};
#pragma pack(pop) #pragma pack(pop)
struct elem { struct elem {
@ -37,25 +34,34 @@ struct elem {
KAVL_HEAD(struct elem) head; 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 i; struct elem main;
unsigned int extra_len;
char *extra;
struct desync_params *dp; struct desync_params *dp;
uint64_t dp_mask; uint64_t dp_mask;
time_t time; time_t time;
}; };
struct mphdr { struct mphdr {
bool static_data; unsigned short flags;
unsigned char cmp_type; unsigned char cmp_type;
size_t count; size_t count;
struct elem *root; 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); void mem_delete(struct mphdr *hdr, const char *str, int len);