The ROme OpTimistic Simulator  2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
hash_map.h
Go to the documentation of this file.
1 
33 #pragma once
34 
35 #include <stdint.h>
36 #include <datatypes/array.h>
37 
38 // TODO DOCUMENTATION!!!
39 
40 #define MAX_LOAD_FACTOR 0.85
41 #define MIN_LOAD_FACTOR 0.05
42 
43 typedef uint32_t map_size_t;
44 typedef map_size_t hash_t;
45 #define HMAP_INVALID_I UINT_MAX
46 typedef unsigned long long key_type_t;
47 
49  map_size_t capacity_mo;
51  unsigned long long key;
52  hash_t hash;
53  unsigned elem_i;
54  } *nodes;
55 };
56 
57 // the type must have a unsigned long long variable named key
58 #define rootsim_hash_map(type) \
59  struct { \
60  rootsim_array(type) elems; \
61  struct _inner_hash_map_t _i_hmap; \
62  }
63 
64 #define hash_map_init(hashmap) ({ \
65  _hash_map_init(&((hashmap)._i_hmap)); \
66  array_init((hashmap).elems); \
67  })
68 
69 #define hash_map_count(hashmap) ({ \
70  array_count((hashmap).elems);\
71  })
72 
73 #define hash_map_fini(hashmap) ({ \
74  _hash_map_fini(&((hashmap)._i_hmap)); \
75  array_fini((hashmap).elems); \
76  })
77 
78 #define hash_map_reserve_elem(hashmap, key) ({ \
79  _hash_map_add(&((hashmap)._i_hmap), key, array_count((hashmap).elems)); \
80  __typeof__(array_items((hashmap).elems)) __ret = array_reserve((hashmap).elems, 1); \
81  assert(__ret); \
82  __ret; \
83  })
84 
85 #define hash_map_lookup(hashmap, key) ({ \
86  map_size_t __lkp_i = _hash_map_lookup(&((hashmap)._i_hmap), key); \
87  __lkp_i != UINT_MAX ? &(array_get_at((hashmap).elems, __lkp_i)) : NULL; \
88  })
89 
90 #define hash_map_delete_elem(hashmap, elem) ({ \
91  assert(array_count((hashmap).elems)); \
92  key_type_t __l_key = array_peek((hashmap).elems).key; \
93  unsigned __rem_i = elem - array_items((hashmap).elems); \
94  _hash_map_remove(&((hashmap)._i_hmap), elem->key, array_count((hashmap).elems)); \
95  _hash_map_update_i(&((hashmap)._i_hmap), __l_key, __rem_i); \
96  array_lazy_remove_at((hashmap).elems, __rem_i); \
97  })
98 
99 #define hash_map_items(hashmap) ({ \
100  assert(array_count((hashmap).elems)); \
101  __typeof__(array_items((hashmap).elems)) __ret = array_items((hashmap).elems); \
102  __ret; \
103  })
104 
105 #define hash_map_dump_size(hashmap) ({ \
106  size_t __ret = array_dump_size((hashmap).elems); \
107  __ret += _hash_map_dump_size(&((hashmap)._i_hmap)); \
108  __ret; \
109  })
110 
111 #define hash_map_dump(hashmap, destination) ({ \
112  array_dump((hashmap).elems, destination); \
113  destination = _hash_map_dump(&((hashmap)._i_hmap), destination); \
114  })
115 
116 #define hash_map_load(hashmap, source) ({ \
117  array_load((hashmap).elems, source); \
118  source = _hash_map_load(&((hashmap)._i_hmap), source); \
119  })
120 
121 
122 // XXX returning and requesting a hash_map_pair_t forces a lot of ugly casts, change it somehow!
123 void _hash_map_init (struct _inner_hash_map_t *_i_hmap);
124 void _hash_map_fini (struct _inner_hash_map_t *_i_hmap);
125 void _hash_map_add (struct _inner_hash_map_t *_i_hmap, unsigned long long key, map_size_t cur_count);
126 unsigned _hash_map_lookup(struct _inner_hash_map_t *_i_hmap, unsigned long long key);
127 void _hash_map_remove(struct _inner_hash_map_t *_i_hmap, unsigned long long key, map_size_t cur_count);
128 void _hash_map_update_i(struct _inner_hash_map_t *_i_hmap, unsigned long long key, map_size_t new_i);
129 inline size_t _hash_map_dump_size(struct _inner_hash_map_t *_i_hmap);
130 inline unsigned char* _hash_map_dump(struct _inner_hash_map_t *_i_hmap, unsigned char *_destination);
131 inline unsigned char* _hash_map_load(struct _inner_hash_map_t *_i_hmap, unsigned char *_source);
This is the implementation of a dynamic array, used for managing various data structures.