LCOV - code coverage report
Current view: top level - metalib_isl/include/isl - hmap_templ.c (source / functions) Hit Total Coverage
Test: 2018-10-31_point_maint_greina16.lcov Lines: 3 178 1.7 %
Date: 2018-11-01 11:27:00 Functions: 1 61 1.6 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2011      INRIA Saclay
       3             :  * Copyright 2013      Ecole Normale Superieure
       4             :  *
       5             :  * Use of this software is governed by the MIT license
       6             :  *
       7             :  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
       8             :  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
       9             :  * 91893 Orsay, France
      10             :  * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
      11             :  */
      12             : 
      13             : #include <isl/ctx.h>
      14             : #include <isl/hash.h>
      15             : 
      16             : #define ISL_xCAT(A,B) A ## B
      17             : #define ISL_CAT(A,B) ISL_xCAT(A,B)
      18             : #define ISL_xFN(TYPE,NAME) TYPE ## _ ## NAME
      19             : #define ISL_FN(TYPE,NAME) ISL_xFN(TYPE,NAME)
      20             : #define ISL_xS(TYPE1,TYPE2,NAME) struct isl_ ## TYPE1 ## _ ## TYPE2 ## _ ## NAME
      21             : #define ISL_yS(TYPE1,TYPE2,NAME) ISL_xS(TYPE1,TYPE2,NAME)
      22             : #define ISL_S(NAME) ISL_yS(ISL_KEY,ISL_VAL,NAME)
      23             : 
      24             : struct ISL_HMAP {
      25             :         int ref;
      26             :         isl_ctx *ctx;
      27             :         struct isl_hash_table table;
      28             : };
      29             : 
      30             : ISL_S(pair) {
      31             :         ISL_KEY *key;
      32             :         ISL_VAL *val;
      33             : };
      34             : 
      35           0 : __isl_give ISL_HMAP *ISL_FN(ISL_HMAP,alloc)(isl_ctx *ctx, int min_size)
      36             : {
      37             :         ISL_HMAP *hmap;
      38             : 
      39           0 :         hmap = isl_calloc_type(ctx, ISL_HMAP);
      40           0 :         if (!hmap)
      41           0 :                 return NULL;
      42             : 
      43           0 :         hmap->ctx = ctx;
      44           0 :         isl_ctx_ref(ctx);
      45           0 :         hmap->ref = 1;
      46             : 
      47           0 :         if (isl_hash_table_init(ctx, &hmap->table, min_size) < 0)
      48           0 :                 return ISL_FN(ISL_HMAP,free)(hmap);
      49             : 
      50           0 :         return hmap;
      51             : }
      52             : 
      53           0 : static isl_stat free_pair(void **entry, void *user)
      54             : {
      55           0 :         ISL_S(pair) *pair = *entry;
      56           0 :         ISL_FN(ISL_KEY,free)(pair->key);
      57           0 :         ISL_FN(ISL_VAL,free)(pair->val);
      58           0 :         free(pair);
      59           0 :         *entry = NULL;
      60           0 :         return isl_stat_ok;
      61             : }
      62             : 
      63      225882 : __isl_null ISL_HMAP *ISL_FN(ISL_HMAP,free)(__isl_take ISL_HMAP *hmap)
      64             : {
      65      225882 :         if (!hmap)
      66      225882 :                 return NULL;
      67           0 :         if (--hmap->ref > 0)
      68           0 :                 return NULL;
      69           0 :         isl_hash_table_foreach(hmap->ctx, &hmap->table, &free_pair, NULL);
      70           0 :         isl_hash_table_clear(&hmap->table);
      71           0 :         isl_ctx_deref(hmap->ctx);
      72           0 :         free(hmap);
      73           0 :         return NULL;
      74             : }
      75             : 
      76           0 : isl_ctx *ISL_FN(ISL_HMAP,get_ctx)(__isl_keep ISL_HMAP *hmap)
      77             : {
      78           0 :         return hmap ? hmap->ctx : NULL;
      79             : }
      80             : 
      81             : /* Add a mapping from "key" to "val" to the associative array
      82             :  * pointed to by user.
      83             :  */
      84           0 : static isl_stat add_key_val(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val,
      85             :         void *user)
      86             : {
      87           0 :         ISL_HMAP **hmap = (ISL_HMAP **) user;
      88             : 
      89           0 :         *hmap = ISL_FN(ISL_HMAP,set)(*hmap, key, val);
      90             : 
      91           0 :         if (!*hmap)
      92           0 :                 return isl_stat_error;
      93             : 
      94           0 :         return isl_stat_ok;
      95             : }
      96             : 
      97           0 : __isl_give ISL_HMAP *ISL_FN(ISL_HMAP,dup)(__isl_keep ISL_HMAP *hmap)
      98             : {
      99             :         ISL_HMAP *dup;
     100             : 
     101           0 :         if (!hmap)
     102           0 :                 return NULL;
     103             : 
     104           0 :         dup = ISL_FN(ISL_HMAP,alloc)(hmap->ctx, hmap->table.n);
     105           0 :         if (ISL_FN(ISL_HMAP,foreach)(hmap, &add_key_val, &dup) < 0)
     106           0 :                 return ISL_FN(ISL_HMAP,free)(dup);
     107             : 
     108           0 :         return dup;
     109             : }
     110             : 
     111           0 : __isl_give ISL_HMAP *ISL_FN(ISL_HMAP,cow)(__isl_take ISL_HMAP *hmap)
     112             : {
     113           0 :         if (!hmap)
     114           0 :                 return NULL;
     115             : 
     116           0 :         if (hmap->ref == 1)
     117           0 :                 return hmap;
     118           0 :         hmap->ref--;
     119           0 :         return ISL_FN(ISL_HMAP,dup)(hmap);
     120             : }
     121             : 
     122           0 : __isl_give ISL_HMAP *ISL_FN(ISL_HMAP,copy)(__isl_keep ISL_HMAP *hmap)
     123             : {
     124           0 :         if (!hmap)
     125           0 :                 return NULL;
     126             : 
     127           0 :         hmap->ref++;
     128           0 :         return hmap;
     129             : }
     130             : 
     131           0 : static int has_key(const void *entry, const void *c_key)
     132             : {
     133           0 :         const ISL_S(pair) *pair = entry;
     134           0 :         ISL_KEY *key = (ISL_KEY *) c_key;
     135             : 
     136           0 :         return ISL_KEY_IS_EQUAL(pair->key, key);
     137             : }
     138             : 
     139             : /* If "hmap" contains a value associated to "key", then return
     140             :  * (isl_bool_true, copy of value).
     141             :  * Otherwise, return
     142             :  * (isl_bool_false, NULL).
     143             :  * If an error occurs, then return
     144             :  * (isl_bool_error, NULL).
     145             :  */
     146           0 : __isl_give ISL_MAYBE(ISL_VAL) ISL_FN(ISL_HMAP,try_get)(
     147             :         __isl_keep ISL_HMAP *hmap, __isl_keep ISL_KEY *key)
     148             : {
     149             :         struct isl_hash_table_entry *entry;
     150             :         ISL_S(pair) *pair;
     151             :         uint32_t hash;
     152           0 :         ISL_MAYBE(ISL_VAL) res = { isl_bool_false, NULL };
     153             : 
     154           0 :         if (!hmap || !key)
     155             :                 goto error;
     156             : 
     157           0 :         hash = ISL_FN(ISL_KEY,get_hash)(key);
     158           0 :         entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash,
     159             :                                         &has_key, key, 0);
     160             : 
     161           0 :         if (!entry)
     162           0 :                 return res;
     163             : 
     164           0 :         pair = entry->data;
     165             : 
     166           0 :         res.valid = isl_bool_true;
     167           0 :         res.value = ISL_FN(ISL_VAL,copy)(pair->val);
     168           0 :         if (!res.value)
     169           0 :                 res.valid = isl_bool_error;
     170           0 :         return res;
     171             : error:
     172           0 :         res.valid = isl_bool_error;
     173           0 :         res.value = NULL;
     174           0 :         return res;
     175             : }
     176             : 
     177             : /* If "hmap" contains a value associated to "key", then return
     178             :  * isl_bool_true.  Otherwise, return isl_bool_false.
     179             :  * Return isl_bool_error on error.
     180             :  */
     181           0 : isl_bool ISL_FN(ISL_HMAP,has)(__isl_keep ISL_HMAP *hmap,
     182             :         __isl_keep ISL_KEY *key)
     183             : {
     184             :         ISL_MAYBE(ISL_VAL) res;
     185             : 
     186           0 :         res = ISL_FN(ISL_HMAP,try_get)(hmap, key);
     187           0 :         ISL_FN(ISL_VAL,free)(res.value);
     188             : 
     189           0 :         return res.valid;
     190             : }
     191             : 
     192             : /* If "hmap" contains a value associated to "key", then return
     193             :  * a copy of that value.  Otherwise, return NULL.
     194             :  * Return NULL on error.
     195             :  */
     196           0 : __isl_give ISL_VAL *ISL_FN(ISL_HMAP,get)(__isl_keep ISL_HMAP *hmap,
     197             :         __isl_take ISL_KEY *key)
     198             : {
     199             :         ISL_VAL *res;
     200             : 
     201           0 :         res = ISL_FN(ISL_HMAP,try_get)(hmap, key).value;
     202           0 :         ISL_FN(ISL_KEY,free)(key);
     203           0 :         return res;
     204             : }
     205             : 
     206             : /* Remove the mapping between "key" and its associated value (if any)
     207             :  * from "hmap".
     208             :  *
     209             :  * If "key" is not mapped to anything, then we leave "hmap" untouched"
     210             :  */
     211           0 : __isl_give ISL_HMAP *ISL_FN(ISL_HMAP,drop)(__isl_take ISL_HMAP *hmap,
     212             :         __isl_take ISL_KEY *key)
     213             : {
     214             :         struct isl_hash_table_entry *entry;
     215             :         ISL_S(pair) *pair;
     216             :         uint32_t hash;
     217             : 
     218           0 :         if (!hmap || !key)
     219             :                 goto error;
     220             : 
     221           0 :         hash = ISL_FN(ISL_KEY,get_hash)(key);
     222           0 :         entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash,
     223             :                                         &has_key, key, 0);
     224           0 :         if (!entry) {
     225           0 :                 ISL_FN(ISL_KEY,free)(key);
     226           0 :                 return hmap;
     227             :         }
     228             : 
     229           0 :         hmap = ISL_FN(ISL_HMAP,cow)(hmap);
     230           0 :         if (!hmap)
     231           0 :                 goto error;
     232           0 :         entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash,
     233             :                                         &has_key, key, 0);
     234           0 :         ISL_FN(ISL_KEY,free)(key);
     235             : 
     236           0 :         if (!entry)
     237           0 :                 isl_die(hmap->ctx, isl_error_internal,
     238             :                         "missing entry" , goto error);
     239             : 
     240           0 :         pair = entry->data;
     241           0 :         isl_hash_table_remove(hmap->ctx, &hmap->table, entry);
     242           0 :         ISL_FN(ISL_KEY,free)(pair->key);
     243           0 :         ISL_FN(ISL_VAL,free)(pair->val);
     244           0 :         free(pair);
     245             : 
     246           0 :         return hmap;
     247             : error:
     248           0 :         ISL_FN(ISL_KEY,free)(key);
     249           0 :         ISL_FN(ISL_HMAP,free)(hmap);
     250           0 :         return NULL;
     251             : }
     252             : 
     253             : /* Add a mapping from "key" to "val" to "hmap".
     254             :  * If "key" was already mapped to something else, then that mapping
     255             :  * is replaced.
     256             :  * If key happened to be mapped to "val" already, then we leave
     257             :  * "hmap" untouched.
     258             :  */
     259           0 : __isl_give ISL_HMAP *ISL_FN(ISL_HMAP,set)(__isl_take ISL_HMAP *hmap,
     260             :         __isl_take ISL_KEY *key, __isl_take ISL_VAL *val)
     261             : {
     262             :         struct isl_hash_table_entry *entry;
     263             :         ISL_S(pair) *pair;
     264             :         uint32_t hash;
     265             : 
     266           0 :         if (!hmap || !key || !val)
     267             :                 goto error;
     268             : 
     269           0 :         hash = ISL_FN(ISL_KEY,get_hash)(key);
     270           0 :         entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash,
     271             :                                         &has_key, key, 0);
     272           0 :         if (entry) {
     273             :                 int equal;
     274           0 :                 pair = entry->data;
     275           0 :                 equal = ISL_VAL_IS_EQUAL(pair->val, val);
     276           0 :                 if (equal < 0)
     277           0 :                         goto error;
     278           0 :                 if (equal) {
     279           0 :                         ISL_FN(ISL_KEY,free)(key);
     280           0 :                         ISL_FN(ISL_VAL,free)(val);
     281           0 :                         return hmap;
     282             :                 }
     283             :         }
     284             : 
     285           0 :         hmap = ISL_FN(ISL_HMAP,cow)(hmap);
     286           0 :         if (!hmap)
     287           0 :                 goto error;
     288             : 
     289           0 :         entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash,
     290             :                                         &has_key, key, 1);
     291             : 
     292           0 :         if (!entry)
     293           0 :                 goto error;
     294             : 
     295           0 :         if (entry->data) {
     296           0 :                 pair = entry->data;
     297           0 :                 ISL_FN(ISL_VAL,free)(pair->val);
     298           0 :                 pair->val = val;
     299           0 :                 ISL_FN(ISL_KEY,free)(key);
     300           0 :                 return hmap;
     301             :         }
     302             : 
     303           0 :         pair = isl_alloc_type(hmap->ctx, ISL_S(pair));
     304           0 :         if (!pair)
     305           0 :                 goto error;
     306             : 
     307           0 :         entry->data = pair;
     308           0 :         pair->key = key;
     309           0 :         pair->val = val;
     310           0 :         return hmap;
     311             : error:
     312           0 :         ISL_FN(ISL_KEY,free)(key);
     313           0 :         ISL_FN(ISL_VAL,free)(val);
     314           0 :         return ISL_FN(ISL_HMAP,free)(hmap);
     315             : }
     316             : 
     317             : /* Internal data structure for isl_map_to_basic_set_foreach.
     318             :  *
     319             :  * fn is the function that should be called on each entry.
     320             :  * user is the user-specified final argument to fn.
     321             :  */
     322             : ISL_S(foreach_data) {
     323             :         isl_stat (*fn)(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val,
     324             :                 void *user);
     325             :         void *user;
     326             : };
     327             : 
     328             : /* Call data->fn on a copy of the key and value in *entry.
     329             :  */
     330           0 : static isl_stat call_on_copy(void **entry, void *user)
     331             : {
     332           0 :         ISL_S(pair) *pair = *entry;
     333           0 :         ISL_S(foreach_data) *data = (ISL_S(foreach_data) *) user;
     334             : 
     335           0 :         return data->fn(ISL_FN(ISL_KEY,copy)(pair->key),
     336             :                         ISL_FN(ISL_VAL,copy)(pair->val), data->user);
     337             : }
     338             : 
     339             : /* Call "fn" on each pair of key and value in "hmap".
     340             :  */
     341           0 : isl_stat ISL_FN(ISL_HMAP,foreach)(__isl_keep ISL_HMAP *hmap,
     342             :         isl_stat (*fn)(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val,
     343             :                 void *user),
     344             :         void *user)
     345             : {
     346           0 :         ISL_S(foreach_data) data = { fn, user };
     347             : 
     348           0 :         if (!hmap)
     349           0 :                 return isl_stat_error;
     350             : 
     351           0 :         return isl_hash_table_foreach(hmap->ctx, &hmap->table,
     352             :                                       &call_on_copy, &data);
     353             : }
     354             : 
     355             : /* Internal data structure for print_pair.
     356             :  *
     357             :  * p is the printer on which the associative array is being printed.
     358             :  * first is set if the current key-value pair is the first to be printed.
     359             :  */
     360             : ISL_S(print_data) {
     361             :         isl_printer *p;
     362             :         int first;
     363             : };
     364             : 
     365             : /* Print the given key-value pair to data->p.
     366             :  */
     367           0 : static isl_stat print_pair(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val,
     368             :         void *user)
     369             : {
     370           0 :         ISL_S(print_data) *data = user;
     371             : 
     372           0 :         if (!data->first)
     373           0 :                 data->p = isl_printer_print_str(data->p, ", ");
     374           0 :         data->p = ISL_KEY_PRINT(data->p, key);
     375           0 :         data->p = isl_printer_print_str(data->p, ": ");
     376           0 :         data->p = ISL_VAL_PRINT(data->p, val);
     377           0 :         data->first = 0;
     378             : 
     379           0 :         ISL_FN(ISL_KEY,free)(key);
     380           0 :         ISL_FN(ISL_VAL,free)(val);
     381           0 :         return isl_stat_ok;
     382             : }
     383             : 
     384             : /* Print the associative array to "p".
     385             :  */
     386           0 : __isl_give isl_printer *ISL_FN(isl_printer_print,ISL_HMAP_SUFFIX)(
     387             :         __isl_take isl_printer *p, __isl_keep ISL_HMAP *hmap)
     388             : {
     389             :         ISL_S(print_data) data;
     390             : 
     391           0 :         if (!p || !hmap)
     392           0 :                 return isl_printer_free(p);
     393             : 
     394           0 :         p = isl_printer_print_str(p, "{");
     395           0 :         data.p = p;
     396           0 :         data.first = 1;
     397           0 :         if (ISL_FN(ISL_HMAP,foreach)(hmap, &print_pair, &data) < 0)
     398           0 :                 data.p = isl_printer_free(data.p);
     399           0 :         p = data.p;
     400           0 :         p = isl_printer_print_str(p, "}");
     401             : 
     402           0 :         return p;
     403             : }
     404             : 
     405           0 : void ISL_FN(ISL_HMAP,dump)(__isl_keep ISL_HMAP *hmap)
     406             : {
     407             :         isl_printer *printer;
     408             : 
     409           0 :         if (!hmap)
     410           0 :                 return;
     411             : 
     412           0 :         printer = isl_printer_to_file(ISL_FN(ISL_HMAP,get_ctx)(hmap), stderr);
     413           0 :         printer = ISL_FN(isl_printer_print,ISL_HMAP_SUFFIX)(printer, hmap);
     414           0 :         printer = isl_printer_end_line(printer);
     415             : 
     416           0 :         isl_printer_free(printer);
     417             : }

Generated by: LCOV version 1.12