optimize name lookup

This commit is contained in:
hippoz 2023-01-22 20:26:46 +02:00
parent 0f69b9b433
commit 0529fd1dde
Signed by: hippoz
GPG key ID: 56C4E02A85F2FBED
2 changed files with 24 additions and 8 deletions

View file

@ -19,12 +19,12 @@
// https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function#FNV-1a_hash // https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function#FNV-1a_hash
uint64_t hashmap_hash(const char *bytes, size_t map_len) static inline uint32_t hashmap_hash(const char *bytes, int map_len)
{ {
uint64_t hash = 0xcbf29ce484222325; uint32_t hash = 0x811c9dc5;
while (*bytes++) { while (*bytes++) {
hash *= 0x100000001b3; hash *= 0x01000193;
hash ^= *bytes; hash ^= *bytes;
} }
@ -105,6 +105,8 @@ Bus *bus_create(const char *socket_path)
for (int i = 0; i < BUS_MAX_NAMES; i++) { for (int i = 0; i < BUS_MAX_NAMES; i++) {
s->names[i].client = NULL; s->names[i].client = NULL;
s->names[i].name = NULL; s->names[i].name = NULL;
s->names[i].root_index = i;
s->names[i].chain_count = 0;
} }
s->names_count = 0; s->names_count = 0;
s->clients_count = 0; s->clients_count = 0;
@ -139,11 +141,15 @@ int bus_client_add(Bus *s, int fd)
return -1; return -1;
} }
int bus_name_find(Bus *s, char *name) static inline int bus_name_find(Bus *s, char *name)
{ {
int bucket = hashmap_hash(name, BUS_MAX_NAMES); int bucket = hashmap_hash(name, BUS_MAX_NAMES);
for (int i = bucket; i < bucket + 12 && i < BUS_MAX_NAMES; i++) { if (s->names[bucket].name && s->names[bucket].chain_count == 0) {
return bucket;
}
for (int i = bucket + 1; i < bucket + 12 && i < BUS_MAX_NAMES; i++) {
if (s->names[i].name && strcmp(s->names[i].name, name) == 0) { if (s->names[i].name && strcmp(s->names[i].name, name) == 0) {
return i; return i;
} }
@ -159,11 +165,11 @@ BusClient *bus_name_find_client(Bus *s, char *name)
return NULL; return NULL;
} }
if (!s->names[name_index].client) { if (unlikely(!s->names[name_index].client)) {
return NULL; return NULL;
} }
if (s->names[name_index].client->state != BUS_CLIENT_STATE_READY) { if (unlikely(s->names[name_index].client->state != BUS_CLIENT_STATE_READY)) {
return NULL; return NULL;
} }
@ -182,6 +188,10 @@ BusName *bus_name_add(Bus *s, char *name, BusClient *client)
if (!s->names[i].client) { if (!s->names[i].client) {
for (int j = 0; j < BUS_NAMES_PER_CLIENT; j++) { for (int j = 0; j < BUS_NAMES_PER_CLIENT; j++) {
if (!client->owned_names[j]) { if (!client->owned_names[j]) {
if (i != bucket) {
s->names[bucket].chain_count++;
}
s->names[i].root_index = bucket;
client->owned_names[j] = &s->names[i]; client->owned_names[j] = &s->names[i];
s->names[i].client = client; s->names[i].client = client;
s->names[i].name = name; s->names[i].name = name;
@ -266,6 +276,9 @@ void bus_name_remove(Bus *s, BusName *name)
name->client = NULL; name->client = NULL;
s->names_count--; s->names_count--;
if (&s->names[name->root_index] != name) {
s->names[name->root_index].chain_count--;
}
} }
void bus_client_remove(Bus *s, BusClient *c) void bus_client_remove(Bus *s, BusClient *c)
@ -284,6 +297,7 @@ void bus_client_remove(Bus *s, BusClient *c)
c->owned_names[j] = NULL; c->owned_names[j] = NULL;
} }
bus_name_remove(s, c->unique_name);
c->unique_name = NULL; c->unique_name = NULL;
c->match_count = 0; c->match_count = 0;
c->fd = -1; c->fd = -1;

View file

@ -33,6 +33,8 @@ enum {
typedef struct bus_name { typedef struct bus_name {
char *name; char *name;
struct bus_client *client; struct bus_client *client;
uint16_t chain_count;
uint16_t root_index;
} BusName; } BusName;
typedef struct bus_client { typedef struct bus_client {