LCOV - code coverage report
Current view: top level - src - hash.cc (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 43 43 100.0 %
Date: 2015-01-12 15:17:13 Functions: 7 7 100.0 %
Branches: 10 10 100.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
       2                 :            : /*
       3                 :            :  * Hash Table
       4                 :            :  * (C) 2013  Jung-Sang Ahn <jungsang.ahn@gmail.com>
       5                 :            :  */
       6                 :            : 
       7                 :            : #include <stdio.h>
       8                 :            : #include <stdlib.h>
       9                 :            : #include "hash.h"
      10                 :            : #include "memleak.h"
      11                 :            : 
      12                 :            : #ifdef _HASH_LOCK
      13                 :            :     #define IFDEF_LOCK(...) __VA_ARGS__
      14                 :            : #else
      15                 :            :     #define IFDEF_LOCK(...)
      16                 :            : #endif
      17                 :            : 
      18                 :            : #ifdef _HASH_TREE
      19                 :   86124161 : int _hash_cmp_wrap(struct avl_node *a, struct avl_node *b, void *aux)
      20                 :            : {
      21                 :            :     return ((struct hash *)aux)->cmp(
      22                 :            :         _get_entry(a, struct hash_elem, avl),
      23                 :   86124161 :         _get_entry(b, struct hash_elem, avl));
      24                 :            : }
      25                 :            : #endif
      26                 :            : 
      27                 :        804 : void hash_init(struct hash *hash, int nbuckets, hash_hash_func *hash_func, hash_cmp_func *cmp_func)
      28                 :            : {
      29                 :            :     int i;
      30                 :        804 :     hash->nbuckets = nbuckets;
      31                 :            : #ifdef _HASH_TREE
      32                 :        804 :     hash->buckets = (struct avl_tree *)malloc(sizeof(struct avl_tree) * hash->nbuckets);
      33                 :            : #else
      34                 :            :     hash->buckets = (struct list *)malloc(sizeof(struct list) * hash->nbuckets);
      35                 :            : #endif
      36                 :            : 
      37                 :            :     IFDEF_LOCK( hash->locks = (spin_t*)malloc(sizeof(spin_t) * hash->nbuckets) );
      38                 :            : 
      39         [ +  + ]:    2894628 :     for (i=0;i<hash->nbuckets;++i){
      40                 :            : #ifdef _HASH_TREE
      41                 :    2893824 :         avl_init(hash->buckets + i, (void *)hash);
      42                 :            : #else
      43                 :            :         list_init(hash->buckets + i);
      44                 :            : #endif
      45                 :            : 
      46                 :            :         IFDEF_LOCK( spin_init(hash->locks + i); );
      47                 :            :     }
      48                 :            : 
      49                 :        804 :     hash->hash_func = hash_func;
      50                 :        804 :     hash->cmp = cmp_func;
      51                 :        804 : }
      52                 :            : 
      53                 :   10454444 : void hash_insert(struct hash *hash, struct hash_elem *e)
      54                 :            : {
      55                 :   10454444 :     int bucket = hash->hash_func(hash, e);
      56                 :            : 
      57                 :            :     IFDEF_LOCK( spin_lock(hash->locks + bucket) );
      58                 :            : 
      59                 :            : #ifdef _HASH_TREE
      60                 :   10454424 :     avl_insert(hash->buckets + bucket, &e->avl, _hash_cmp_wrap);
      61                 :            : #else
      62                 :            :     list_push_back(hash->buckets + bucket, &e->list_elem);
      63                 :            : #endif
      64                 :            : 
      65                 :            :     IFDEF_LOCK( spin_unlock(hash->locks + bucket) );
      66                 :   10454334 : }
      67                 :            : 
      68                 :   39935235 : struct hash_elem * hash_find(struct hash *ht, struct hash_elem *e)
      69                 :            : {
      70                 :   39935235 :     int bucket = ht->hash_func(ht, e);
      71                 :   39933515 :     struct hash_elem *elem = NULL;
      72                 :            : 
      73                 :            :     IFDEF_LOCK( spin_lock(ht->locks + bucket) );
      74                 :            : 
      75                 :            : #ifdef _HASH_TREE
      76                 :            :     struct avl_node *node;
      77                 :   39933515 :     node = avl_search(ht->buckets + bucket, &e->avl, _hash_cmp_wrap);
      78         [ +  + ]:   39937960 :     if (node) {
      79                 :            :         IFDEF_LOCK( spin_unlock(ht->locks + bucket) );
      80                 :   29150368 :         elem = _get_entry(node, struct hash_elem, avl);
      81                 :   29150368 :         return elem;
      82                 :            :     }
      83                 :            : #else
      84                 :            :     struct list_elem *le = list_begin(ht->buckets + bucket);
      85                 :            :     while(le) {
      86                 :            :         elem = _get_entry(le, struct hash_elem, list_elem);
      87                 :            :         if (!ht->cmp(e, elem)) {
      88                 :            :             IFDEF_LOCK( spin_unlock(ht->locks + bucket) );
      89                 :            :             return elem;
      90                 :            :         }
      91                 :            :         le = list_next(le);
      92                 :            :     }
      93                 :            : #endif
      94                 :            : 
      95                 :            :     IFDEF_LOCK( spin_unlock(ht->locks + bucket) );
      96                 :   39937960 :     return NULL;
      97                 :            : }
      98                 :            : 
      99                 :   10452696 : struct hash_elem * hash_remove(struct hash *hash, struct hash_elem *e)
     100                 :            : {
     101                 :   10452696 :     int bucket = hash->hash_func(hash, e);
     102                 :            :     struct hash_elem *hash_elem;
     103                 :            : 
     104                 :            :     IFDEF_LOCK( spin_lock(hash->locks + bucket) );
     105                 :            : 
     106                 :            : #ifdef _HASH_TREE
     107                 :            :     struct avl_node *node;
     108                 :   10453258 :     node = avl_search(hash->buckets + bucket, &e->avl, _hash_cmp_wrap);
     109         [ +  + ]:   10453507 :     if (node) {
     110                 :   10453489 :         avl_remove(hash->buckets + bucket, node);
     111                 :            :         IFDEF_LOCK( spin_unlock(hash->locks + bucket) );
     112                 :   10453130 :         hash_elem = _get_entry(node, struct hash_elem, avl);
     113                 :   10453130 :         return hash_elem;
     114                 :            :     }
     115                 :            : 
     116                 :            : #else
     117                 :            :     struct list_elem *le;
     118                 :            :     le = list_begin(hash->buckets + bucket);
     119                 :            :     while(le) {
     120                 :            :         hash_elem = _get_entry(le, struct hash_elem, list_elem);
     121                 :            :         if (!hash->cmp(e, hash_elem)) {
     122                 :            :             list_remove(hash->buckets + bucket, le);
     123                 :            : 
     124                 :            :             IFDEF_LOCK( spin_unlock(hash->locks + bucket) );
     125                 :            : 
     126                 :            :             return hash_elem;
     127                 :            :         }
     128                 :            :         le = list_next(le);
     129                 :            :     }
     130                 :            : #endif
     131                 :            : 
     132                 :            :     IFDEF_LOCK( spin_unlock(hash->locks + bucket) );
     133                 :            : 
     134                 :   10453148 :     return NULL;
     135                 :            : }
     136                 :            : 
     137                 :        798 : void hash_free(struct hash *hash)
     138                 :            : {
     139                 :        798 :     free(hash->buckets);
     140                 :            :     IFDEF_LOCK( free((void *)hash->locks) );
     141                 :        798 : }
     142                 :            : 
     143                 :        179 : void hash_free_active(struct hash *hash, hash_free_func *free_func)
     144                 :            : {
     145                 :            :     int i;
     146                 :            : 
     147                 :            : #ifdef _HASH_TREE
     148                 :            :     struct avl_node *node;
     149                 :            : #else
     150                 :            :     struct list_elem *e, *e_next;
     151                 :            : #endif
     152                 :            : 
     153                 :            :     struct hash_elem *h;
     154                 :            : 
     155         [ +  + ]:     355507 :     for (i=0;i<hash->nbuckets;++i){
     156                 :            : #ifdef _HASH_TREE
     157                 :     355328 :         node = avl_first(hash->buckets + i);
     158         [ +  + ]:     355329 :         while(node){
     159                 :          1 :             h = _get_entry(node, struct hash_elem, avl);
     160                 :          1 :             node = avl_next(node);
     161                 :          1 :             avl_remove(hash->buckets + i, &h->avl);
     162                 :          1 :             free_func(h);
     163                 :            :         }
     164                 :            : 
     165                 :            : #else
     166                 :            :         e = list_begin(hash->buckets + i);
     167                 :            :         while(e) {
     168                 :            :             e_next = list_remove(hash->buckets + i, e);
     169                 :            :             h = _get_entry(e, struct hash_elem, list_elem);
     170                 :            :             free_func(h);
     171                 :            :             e = e_next;
     172                 :            :         }
     173                 :            : 
     174                 :            : #endif
     175                 :            :     }
     176                 :            : 
     177                 :        179 :     hash_free(hash);
     178                 :        179 : }
     179                 :            : 

Generated by: LCOV version 1.11