freeswitch APR library hash table

Posted by racing_fire on Wed, 01 Dec 2021 08:51:41 +0100

 

summary

The core source code of freeswitch is developed based on apr library, which has good portability on different systems.

Hash table is widely used in development. The main scenario is the logic that requires high query efficiency. It is a typical data structure implementation of space for time.

Most of the underlying libraries have their own hash table implementation methods, so how to implement the hash table in the apr library, and what are the advantages and disadvantages?

Let's introduce the hash table implementation of apr library.

environment

centos: CentOS   release 7.0 (Final) or above

freeswitch: v1.8.7

GCC: 4.8.5

Hash table data structure

The hash table source code file of apr library is in libs/apr directory.

libs\apr\include\apr_hash.h

libs\apr\tables\apr_hash.c

The hash table structure is defined in apr_hash.c.

struct apr_hash_entry_t {

    apr_hash_entry_t *next;

    unsigned int      hash;

    const void       *key;

    apr_ssize_t       klen;

    const void       *val;

};



struct apr_hash_index_t {

    apr_hash_t         *ht;

    apr_hash_entry_t   *this, *next;

    unsigned int        index;

};



struct apr_hash_t {

    apr_pool_t          *pool;

    apr_hash_entry_t   **array;

    apr_hash_index_t     iterator;  /* For apr_hash_first(NULL, ...) */

    unsigned int         count, max;

    apr_hashfunc_t       hash_func;

    apr_hash_entry_t    *free;  /* List of recycled entries */

};

 

Common functions

View the source code header file libs\apr\include\apr_hash.h.

apr_hashfunc_default          //Default hash function

apr_hash_make                   //Create hash table

apr_hash_make_custom      //Create a hash table and customize the hash function

apr_hash_copy                    //Copy hash table

apr_hash_set                       //Insert a new key value pair into the hash table

apr_hash_get                      //The hash table looks up the value corresponding to the key

apr_hash_first                     //hash table traversal, first node

apr_hash_next                     //hash table traversal, next node

apr_hash_this                      //The hash table is traversed to obtain the content of the current node

apr_hash_count                  //hash table key value pair count

apr_hash_clear                    //Clear all key value pairs

apr_hash_overlay                //Merge two hash tables

apr_hash_merge                 //Merge two hash tables and customize the conflict handling function

apr_hashfunc_default default hash function

The default hash function of the apr library hash table uses the times33 hash algorithm. The times33 algorithm is very simple, which is to multiply 33 continuously.

For string type key s, the times33 algorithm is easy to use, the calculation is fast, and the hash results are evenly distributed.

The core code is as follows:

if (*klen == APR_HASH_KEY_STRING) {

    for (p = key; *p; p++) {

        hash = hash * 33 + *p;

    }

    *klen = p - key;

}

else {

    for (p = key, i = *klen; i; i--, p++) {

        hash = hash * 33 + *p;

    }

}

apr_hash_make create

The creation function of the apr library hash table.

  1. Allocate APR from memory pool_ hash_ T size of memory.
  2. Field initialization, including memory pool pointer assignment, free pointer is set to NULL, count is set to 0, and max is INITIAL_MAX (15), array pointer, array memory allocation, hash function uses apr_hashfunc_default.

 

apr_hash_set insert

apr library hash table, insert key value pairs.

  1. Find. Calculate the hash value according to the key, and find the key under the array [hash & HT - > Max] corresponding to the hash value. If the key already exists, return the current entry. If the key does not exist, get the entry from the free linked list first. Otherwise, create a new entry and return it.
  2. Check the obtained entry. If the incoming val value is empty, the entry will be deleted and added to the free linked list. If the incoming val value is normal, replace the val field in the entry.
  3. Check to expand the hash table when the count exceeds max.
  4. When expanding the hash table, create new_array, new_ The max size is (max * 2 + 1). Traverse the array and assign a value to new_array and switch the array.

apr_hash_get lookup

Logic of apr hash table lookup:

Calculate the hash value according to the key, and find the key under the array [hash & HT - > Max] corresponding to the hash value. If the key exists, return the val value in the current entry. NULL if the key does not exist.

apr_hash_clear clear

The logic of clearing the apr hash table:

Traverse the hash table and set the val in all entry nodes to NULL.

So, APR_ hash_ After clear, the hash table is not empty, but the val of all entry nodes is empty and the entry is placed in the free linked list.

 

summary

The hash table of the apr library is sufficient for most scenarios. However, there are some special scenarios to consider the possibility of problems.

The apr library hash table is not thread safe.

The hash table of apr library does not further deal with the conflict. When the length of the entry linked list under array[i] exceeds a certain threshold, some methods are used to reduce the conflict, such as capacity expansion, modifying the hash algorithm, using red black tree instead of linked list in entry, etc.

Empty as usual

Be true

Topics: CentOS HashMap sip VOIP