Meant for testing. Defeats some of the benefits of the implementation, however it still seems to be better than the current hash table, and the complexity is undeniably very low. --- src/util/pointer_map.c | 99 +++++++++++++++++--------------------------------- src/util/pointer_map.h | 1 - 2 files changed, 33 insertions(+), 67 deletions(-)
diff --git a/src/util/pointer_map.c b/src/util/pointer_map.c index 463fa19282..7632218b91 100644 --- a/src/util/pointer_map.c +++ b/src/util/pointer_map.c @@ -39,28 +39,25 @@ #include "ralloc.h" #include "macros.h" -static inline uint8_t -get_hash(uint8_t *metadata) -{ - return *metadata & 0x7F; -} +static const uint32_t deleted_key_value; +static const void *deleted_key = &deleted_key_value; -static inline void -set_hash(uint8_t *metadata, uint32_t hash) +static bool +entry_is_free(const struct map_entry *entry) { - *metadata = (*metadata & ~0x7F) | (((uint8_t) hash) & 0x7F); + return entry->key == NULL; } -static inline bool -entry_is_free(uint8_t *metadata) +static bool +entry_is_deleted(const struct pointer_map *pm, struct map_entry *entry) { - return !(*metadata >> 7); + return entry->key == pm->deleted_key; } -static inline void -set_occupied(uint8_t *metadata, bool occupied) +static bool +entry_is_present(const struct pointer_map *pm, struct map_entry *entry) { - *metadata = occupied ? *metadata | 0x80 : *metadata & 0x7F; + return entry->key != NULL && entry->key != pm->deleted_key; } static inline uint32_t @@ -70,15 +67,6 @@ hash_pointer(const void *pointer) return (uint32_t) ((num >> 2) ^ (num >> 6) ^ (num >> 10) ^ (num >> 14)); } -static bool -entry_is_deleted(struct pointer_map *map, uint8_t *metadata) -{ - if (get_hash(metadata) != 0) - return false; - - return map->map[metadata - map->metadata].key == NULL; -} - struct pointer_map * _mesa_pointer_map_create(void *mem_ctx) { @@ -91,9 +79,9 @@ _mesa_pointer_map_create(void *mem_ctx) map->size = 1 << 4; map->max_entries = map->size * 0.6; map->map = rzalloc_array(map, struct map_entry, map->size); - map->metadata = rzalloc_array(map, uint8_t, map->size); map->entries = 0; map->deleted_entries = 0; + map->deleted_key = deleted_key; if (map->map == NULL) { ralloc_free(map); @@ -113,15 +101,13 @@ _mesa_pointer_map_clone(struct pointer_map *src, void *dst_mem_ctx) memcpy(pm, src, sizeof(struct pointer_map)); pm->map = ralloc_array(pm, struct map_entry, pm->size); - pm->metadata = ralloc_array(pm, uint8_t, pm->size); - if (pm->map == NULL || pm->metadata == NULL) { + if (pm->map == NULL) { ralloc_free(pm); return NULL; } memcpy(pm->map, src->map, pm->size * sizeof(struct map_entry)); - memcpy(pm->metadata, src->metadata, pm->size * sizeof(uint8_t)); return pm; } @@ -154,7 +140,6 @@ _mesa_pointer_map_destroy(struct pointer_map *map, void _mesa_pointer_map_clear(struct pointer_map *map) { - memset(map->metadata, 0, map->size * sizeof(uint8_t)); memset(map->map, 0, sizeof(struct map_entry) * map->size); map->entries = 0; map->deleted_entries = 0; @@ -173,15 +158,14 @@ _mesa_pointer_map_search(struct pointer_map *map, const void *key) uint32_t start_hash_address = hash & (map->size - 1); uint32_t hash_address = start_hash_address; + struct map_entry *entry = NULL; do { - uint8_t *metadata = map->metadata + hash_address; + entry = map->map + hash_address; - if (entry_is_free(metadata)) { + if (entry_is_free(entry)) { return NULL; - } else if (get_hash(metadata) == (hash & 0x7F)) { - if (map->map[hash_address].key == key) { - return &map->map[hash_address]; - } + } else if (entry->key == key) { + return entry; } hash_address = (hash_address + 1) & (map->size - 1); @@ -195,7 +179,6 @@ _mesa_pointer_map_rehash(struct pointer_map *map, unsigned new_size) { struct pointer_map old_map; struct map_entry *map_entries, *entry; - uint8_t *metadatas; old_map = *map; @@ -206,12 +189,7 @@ _mesa_pointer_map_rehash(struct pointer_map *map, unsigned new_size) if (map_entries == NULL) return; - metadatas = rzalloc_array(map, uint8_t, map->size); - if (metadatas == NULL) - return; - map->map = map_entries; - map->metadata = metadatas; map->entries = 0; map->deleted_entries = 0; @@ -220,7 +198,6 @@ _mesa_pointer_map_rehash(struct pointer_map *map, unsigned new_size) } ralloc_free(old_map.map); - ralloc_free(old_map.metadata); } /** @@ -232,7 +209,7 @@ struct map_entry * _mesa_pointer_map_insert(struct pointer_map *map, const void *key, void *data) { uint32_t start_hash_address, hash_address, hash; - uint8_t *available_entry = NULL; + struct map_entry *available_entry = NULL; assert(key != NULL); if (map->entries >= map->max_entries) { @@ -245,16 +222,17 @@ _mesa_pointer_map_insert(struct pointer_map *map, const void *key, void *data) start_hash_address = hash & (map->size - 1); hash_address = start_hash_address; + struct map_entry *entry = NULL; + do { - uint8_t *entry = map->metadata + hash_address; + entry = map->map + hash_address; - if (entry_is_free(entry)) { - /* If we have not found a deleted entry yet, then we want - * to take the free slot at the end of the group - */ + if (!entry_is_present(map, entry)) { + /* Stash the first available entry we find */ if (available_entry == NULL) available_entry = entry; - break; + if (entry_is_free(entry)) + break; } /* Implement replacement when another insert happens @@ -268,18 +246,9 @@ _mesa_pointer_map_insert(struct pointer_map *map, const void *key, void *data) * required to avoid memory leaks, perform a search * before inserting. */ - if (get_hash(entry) == (hash & 0x7F) && - map->map[hash_address].key == key) { - set_hash(entry, hash); - map->map[hash_address].data = data; - set_occupied(entry, true); - return &map->map[hash_address]; - } - - // Stash the first deleted entry in the group - if (entry_is_deleted(map, entry) && - available_entry == NULL) { - available_entry = entry; + if (!entry_is_deleted(map, entry) && key == entry->key) { + entry->data = data; + return entry; } hash_address = (hash_address + 1) & (map->size - 1); @@ -288,12 +257,10 @@ _mesa_pointer_map_insert(struct pointer_map *map, const void *key, void *data) if (available_entry) { if (entry_is_deleted(map, available_entry)) map->deleted_entries--; - set_hash(available_entry, hash); - set_occupied(available_entry, true); - map->map[hash_address].key = key; - map->map[hash_address].data = data; + available_entry->key = key; + available_entry->data = data; map->entries++; - return &map->map[hash_address]; + return available_entry; } /* We could hit here if a required resize failed. An unchecked-malloc @@ -316,7 +283,7 @@ _mesa_pointer_map_remove(struct pointer_map *map, return; entry->key = NULL; - set_hash(map->metadata + (entry - map->map), 0); + entry->key = map->deleted_key; map->entries--; map->deleted_entries++; } diff --git a/src/util/pointer_map.h b/src/util/pointer_map.h index f92e67d40d..0eccb8a4bd 100644 --- a/src/util/pointer_map.h +++ b/src/util/pointer_map.h @@ -42,7 +42,6 @@ struct map_entry { struct pointer_map { struct map_entry *map; - uint8_t *metadata; const void *deleted_key; -- 2.16.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev