From 7252befc177428355ca5430aa943a9d913c2e0ce Mon Sep 17 00:00:00 2001 From: Marko Viitanen Date: Wed, 21 Jun 2023 22:08:41 +0300 Subject: [PATCH] [ibc] Add a hashmap implementation for IBC hash search --- CMakeLists.txt | 2 +- src/hashmap.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++ src/hashmap.h | 60 ++++++++++++++++++++ 3 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 src/hashmap.c create mode 100644 src/hashmap.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 99fa8a88..2af1420e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -200,7 +200,7 @@ file(GLOB SOURCE_GROUP_CABAC RELATIVE ${PROJECT_SOURCE_DIR} "src/bitstream.*" "s file(GLOB SOURCE_GROUP_COMPRESSION RELATIVE ${PROJECT_SOURCE_DIR} "src/search*" "src/rdo.*" "src/fast_coeff*") file(GLOB SOURCE_GROUP_CONSTRAINT RELATIVE ${PROJECT_SOURCE_DIR} "src/constraint.*" "src/ml_*") file(GLOB SOURCE_GROUP_CONTROL RELATIVE ${PROJECT_SOURCE_DIR} "src/cfg.*" "src/encoder.*" "src/encoder_state-c*" "src/encoder_state-g*" "src/encoderstate*" "src/gop.*" "src/input_frame_buffer.*" "src/uvg266*" "src/rate_control.*" "src/mip_data.h") -file(GLOB SOURCE_GROUP_DATA_STRUCTURES RELATIVE ${PROJECT_SOURCE_DIR} "src/cu.*" "src/image.*" "src/imagelist.*" "src/videoframe.*") +file(GLOB SOURCE_GROUP_DATA_STRUCTURES RELATIVE ${PROJECT_SOURCE_DIR} "src/cu.*" "src/image.*" "src/imagelist.*" "src/videoframe.*" "src/hashmap.*") file(GLOB SOURCE_GROUP_EXTRAS RELATIVE ${PROJECT_SOURCE_DIR} "src/extras/*.h" "src/extras/*.c") file(GLOB_RECURSE SOURCE_GROUP_STRATEGIES RELATIVE ${PROJECT_SOURCE_DIR} "src/strategies/*.h" "src/strategies/*.c") file(GLOB SOURCE_GROUP_RECON RELATIVE ${PROJECT_SOURCE_DIR} "src/alf.*" "src/filter.*" "src/inter.*" "src/intra.*" "src/reshape.*" "src/sao.*" "src/scalinglist.*" "src/tables.*" "src/transform.*") diff --git a/src/hashmap.c b/src/hashmap.c new file mode 100644 index 00000000..3e9c0890 --- /dev/null +++ b/src/hashmap.c @@ -0,0 +1,145 @@ +/***************************************************************************** + * This file is part of uvg266 VVC encoder. + * + * Copyright (c) 2023, Tampere University, ITU/ISO/IEC, project contributors + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * * Neither the name of the Tampere University or ITU/ISO/IEC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS + ****************************************************************************/ + +#include "hashmap.h" + +/** + * \brief This function creates a node for the uvg_hashmap. + * + * \param key the key of the node to be created + * \param value the value of the node to be created + * \return uvg_hashmap_node a node with the given key and value + */ +uvg_hashmap_node* uvg_hashmap_create_node(uint32_t key, uint32_t value) { + uvg_hashmap_node* new_node = (uvg_hashmap_node*)malloc(sizeof(uvg_hashmap_node)); + new_node->key = key; + new_node->value = value; + new_node->next = NULL; + return new_node; +} + +/** + * \brief This function creates a new uvg_hashmap with a given bucket size. + * + * \param bucket_size the size of the hashmap bucket + * \return uvg_hashmap a new uvg_hashmap with the given bucket size + */ +uvg_hashmap* uvg_hashmap_create(uint32_t bucket_size) +{ + uvg_hashmap* new_hashmap = (uvg_hashmap*)malloc(sizeof(uvg_hashmap)); + new_hashmap->bucket_size = bucket_size; + new_hashmap->table = (uvg_hashmap_node**)malloc(sizeof(uvg_hashmap_node*) * bucket_size); + for (int i = 0; i < bucket_size; i++) { + new_hashmap->table[i] = NULL; + } + return new_hashmap; +} + +/** + * \brief This function calculates the hash index for a given + * key and bucket size using the Jenkins hash function. + * + * \param key the key to be hashed + * \param bucket_size the size of the hashmap bucket + * \return the hashed index for the given key and bucket size. + */ +uint32_t uvg_hashmap_hash(uint32_t key, uint32_t bucket_size) { + key ^= (key >> 20) ^ (key >> 12); + return (key ^ (key >> 7) ^ (key >> 4) ^ 2654435769U) % bucket_size; +} + +/** + * \brief This function inserts a new node into the hashmap. + * + * \param map the hashmap to insert the new node into + * \param key the key of the new node + * \param value the value of the new node + */ +void uvg_hashmap_insert(uvg_hashmap* map, uint32_t key, uint32_t value) { + uint32_t hash_index = uvg_hashmap_hash(key, map->bucket_size); + uvg_hashmap_node* new_node = uvg_hashmap_create_node(key, value); + new_node->next = map->table[hash_index]; + map->table[hash_index] = new_node; +} + +/** + * \brief This function searches the hashmap for the given key. + * + * \param map the hashmap to search in + * \param key the key to search for + * \return uvg_hashmap_node the node with the given key, NULL if not found. + */ +uvg_hashmap_node* uvg_hashmap_search(uvg_hashmap* map, uint32_t key) { + uint32_t hashIndex = uvg_hashmap_hash(key, map->bucket_size); + uvg_hashmap_node* temp = map->table[hashIndex]; + uvg_hashmap_node* return_node = NULL; + // Search key in chain and return all of them + while (temp) { + if (temp->key == key) { + uvg_hashmap_node* new_node = uvg_hashmap_create_node(key, temp->value); + if (return_node != NULL) { + new_node->next = return_node; + } + return_node = new_node; + } + temp = temp->next; + } + return return_node; +} + +/** + * \brief This function frees the memory of a given hashmap node. + * + * \param node the node to free the memory of. + */ +void uvg_hashmap_node_free(uvg_hashmap_node* node) +{ + while (node) { + uvg_hashmap_node* to_delete = node; + node = node->next; + free(to_delete); + } +} + +/** + * \brief This function frees the memory of a given hashmap. + * + * \param map the hashmap to free the memory of. + */ +void uvg_hashmap_free(uvg_hashmap* map) { + for (int i = 0; i < map->bucket_size; i++) { + uvg_hashmap_node* temp = map->table[i]; + uvg_hashmap_node_free(temp); + } + free(map->table); + free(map); +} diff --git a/src/hashmap.h b/src/hashmap.h new file mode 100644 index 00000000..61e868bf --- /dev/null +++ b/src/hashmap.h @@ -0,0 +1,60 @@ +/***************************************************************************** + * This file is part of uvg266 VVC encoder. + * + * Copyright (c) 2023, Tampere University, ITU/ISO/IEC, project contributors + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * * Neither the name of the Tampere University or ITU/ISO/IEC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS + ****************************************************************************/ + +#include +#include +#include + +typedef struct uvg_hashmap_node { + uint32_t key; + uint32_t value; + struct uvg_hashmap_node* next; +} uvg_hashmap_node; + +typedef struct uvg_hashmap { + uint32_t bucket_size; + uvg_hashmap_node** table; +} uvg_hashmap; + +uvg_hashmap_node* uvg_hashmap_create_node(uint32_t key, uint32_t value); + +uvg_hashmap* uvg_hashmap_create(uint32_t bucket_size); + +uint32_t uvg_hashmap_hash(uint32_t key); + +void uvg_hashmap_insert(uvg_hashmap* map, uint32_t key, uint32_t value); + +uvg_hashmap_node* uvg_hashmap_search(uvg_hashmap* map, uint32_t key); + +void uvg_hashmap_node_free(uvg_hashmap_node* node); + +void uvg_hashmap_free(uvg_hashmap* map);