mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-10-06 09:09:03 +00:00
ss: speedup resolve_service()
Lets implement a full cache with proper hash table, memory got cheaper these days. Before : $ time ss -t | wc -l 529678 real 0m22.708s user 0m19.591s sys 0m2.969s After : $ time ss -t | wc -l 528291 real 0m5.078s user 0m4.099s sys 0m0.985s Signed-off-by: Eric Dumazet <edumazet@google.com>
This commit is contained in:
parent
d2055ea597
commit
22588a0e65
57
misc/ss.c
57
misc/ss.c
@ -858,8 +858,7 @@ static const char *print_ms_timer(int timeout)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct scache
|
struct scache {
|
||||||
{
|
|
||||||
struct scache *next;
|
struct scache *next;
|
||||||
int port;
|
int port;
|
||||||
char *name;
|
char *name;
|
||||||
@ -949,11 +948,15 @@ static const char *__resolve_service(int port)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SCACHE_BUCKETS 1024
|
||||||
|
static struct scache *cache_htab[SCACHE_BUCKETS];
|
||||||
|
|
||||||
static const char *resolve_service(int port)
|
static const char *resolve_service(int port)
|
||||||
{
|
{
|
||||||
static char buf[128];
|
static char buf[128];
|
||||||
static struct scache cache[256];
|
struct scache *c;
|
||||||
|
const char *res;
|
||||||
|
int hash;
|
||||||
|
|
||||||
if (port == 0) {
|
if (port == 0) {
|
||||||
buf[0] = '*';
|
buf[0] = '*';
|
||||||
@ -961,45 +964,35 @@ static const char *resolve_service(int port)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolve_services) {
|
if (!resolve_services)
|
||||||
if (dg_proto == RAW_PROTO) {
|
goto do_numeric;
|
||||||
|
|
||||||
|
if (dg_proto == RAW_PROTO)
|
||||||
return inet_proto_n2a(port, buf, sizeof(buf));
|
return inet_proto_n2a(port, buf, sizeof(buf));
|
||||||
} else {
|
|
||||||
struct scache *c;
|
|
||||||
const char *res;
|
|
||||||
int hash = (port^(((unsigned long)dg_proto)>>2))&255;
|
|
||||||
|
|
||||||
for (c = &cache[hash]; c; c = c->next) {
|
|
||||||
if (c->port == port &&
|
hash = (port^(((unsigned long)dg_proto)>>2)) % SCACHE_BUCKETS;
|
||||||
c->proto == dg_proto) {
|
|
||||||
if (c->name)
|
for (c = cache_htab[hash]; c; c = c->next) {
|
||||||
return c->name;
|
if (c->port == port && c->proto == dg_proto)
|
||||||
goto do_numeric;
|
goto do_cache;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((res = __resolve_service(port)) != NULL) {
|
c = malloc(sizeof(*c));
|
||||||
if ((c = malloc(sizeof(*c))) == NULL)
|
if (!c)
|
||||||
goto do_numeric;
|
goto do_numeric;
|
||||||
} else {
|
res = __resolve_service(port);
|
||||||
c = &cache[hash];
|
|
||||||
if (c->name)
|
|
||||||
free(c->name);
|
|
||||||
}
|
|
||||||
c->port = port;
|
c->port = port;
|
||||||
c->name = NULL;
|
c->name = res ? strdup(res) : NULL;
|
||||||
c->proto = dg_proto;
|
c->proto = dg_proto;
|
||||||
if (res) {
|
c->next = cache_htab[hash];
|
||||||
c->name = strdup(res);
|
cache_htab[hash] = c;
|
||||||
c->next = cache[hash].next;
|
|
||||||
cache[hash].next = c;
|
do_cache:
|
||||||
}
|
|
||||||
if (c->name)
|
if (c->name)
|
||||||
return c->name;
|
return c->name;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do_numeric:
|
do_numeric:
|
||||||
sprintf(buf, "%u", port);
|
sprintf(buf, "%u", port);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user