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 };
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;

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 *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();

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)
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));
}

28
mpool.h
View File

@ -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);