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
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++) {
hash *= 0x100000001b3;
hash *= 0x01000193;
hash ^= *bytes;
}
@ -105,6 +105,8 @@ Bus *bus_create(const char *socket_path)
for (int i = 0; i < BUS_MAX_NAMES; i++) {
s->names[i].client = NULL;
s->names[i].name = NULL;
s->names[i].root_index = i;
s->names[i].chain_count = 0;
}
s->names_count = 0;
s->clients_count = 0;
@ -139,11 +141,15 @@ int bus_client_add(Bus *s, int fd)
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);
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) {
return i;
}
@ -158,12 +164,12 @@ BusClient *bus_name_find_client(Bus *s, char *name)
if (name_index < 0) {
return NULL;
}
if (!s->names[name_index].client) {
if (unlikely(!s->names[name_index].client)) {
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;
}
@ -182,6 +188,10 @@ BusName *bus_name_add(Bus *s, char *name, BusClient *client)
if (!s->names[i].client) {
for (int j = 0; j < BUS_NAMES_PER_CLIENT; 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];
s->names[i].client = client;
s->names[i].name = name;
@ -266,6 +276,9 @@ void bus_name_remove(Bus *s, BusName *name)
name->client = NULL;
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)
@ -284,6 +297,7 @@ void bus_client_remove(Bus *s, BusClient *c)
c->owned_names[j] = NULL;
}
bus_name_remove(s, c->unique_name);
c->unique_name = NULL;
c->match_count = 0;
c->fd = -1;

View file

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