src/hash_map.c

changeset 1341
dc88d2ece7e4
parent 1115
6db21dee4929
equal deleted inserted replaced
1340:31c61b6dcaa5 1341:dc88d2ece7e4
76 76
77 // free the map structure 77 // free the map structure
78 cxFree(map->collection.allocator, map); 78 cxFree(map->collection.allocator, map);
79 } 79 }
80 80
81 static int cx_hash_map_put( 81 static void *cx_hash_map_put(
82 CxMap *map, 82 CxMap *map,
83 CxHashKey key, 83 CxHashKey key,
84 void *value 84 void *value
85 ) { 85 ) {
86 struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map; 86 struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map;
103 103
104 if (elm != NULL && elm->key.hash == hash && elm->key.len == key.len && 104 if (elm != NULL && elm->key.hash == hash && elm->key.len == key.len &&
105 memcmp(elm->key.data, key.data, key.len) == 0) { 105 memcmp(elm->key.data, key.data, key.len) == 0) {
106 // overwrite existing element, but call destructors first 106 // overwrite existing element, but call destructors first
107 cx_invoke_destructor(map, elm->data); 107 cx_invoke_destructor(map, elm->data);
108 if (map->collection.store_pointer) { 108 if (value == NULL) {
109 memset(elm->data, 0, map->collection.elem_size);
110 } else if (map->collection.store_pointer) {
109 memcpy(elm->data, &value, sizeof(void *)); 111 memcpy(elm->data, &value, sizeof(void *));
110 } else { 112 } else {
111 memcpy(elm->data, value, map->collection.elem_size); 113 memcpy(elm->data, value, map->collection.elem_size);
112 } 114 }
113 } else { 115 } else {
114 // allocate new element 116 // allocate new element
115 struct cx_hash_map_element_s *e = cxMalloc( 117 struct cx_hash_map_element_s *e = cxMalloc(
116 allocator, 118 allocator,
117 sizeof(struct cx_hash_map_element_s) + map->collection.elem_size 119 sizeof(struct cx_hash_map_element_s) + map->collection.elem_size
118 ); 120 );
119 if (e == NULL) return -1; 121 if (e == NULL) return NULL;
120 122
121 // write the value 123 // write the value
122 if (map->collection.store_pointer) { 124 if (value == NULL) {
125 memset(e->data, 0, map->collection.elem_size);
126 } else if (map->collection.store_pointer) {
123 memcpy(e->data, &value, sizeof(void *)); 127 memcpy(e->data, &value, sizeof(void *));
124 } else { 128 } else {
125 memcpy(e->data, value, map->collection.elem_size); 129 memcpy(e->data, value, map->collection.elem_size);
126 } 130 }
127 131
128 // copy the key 132 // copy the key
129 void *kd = cxMalloc(allocator, key.len); 133 void *kd = cxMalloc(allocator, key.len);
130 if (kd == NULL) return -1; 134 if (kd == NULL) {
135 cxFree(allocator, e);
136 return NULL;
137 }
131 memcpy(kd, key.data, key.len); 138 memcpy(kd, key.data, key.len);
132 e->key.data = kd; 139 e->key.data = kd;
133 e->key.len = key.len; 140 e->key.len = key.len;
134 e->key.hash = hash; 141 e->key.hash = hash;
135 142
138 hash_map->buckets[slot] = e; 145 hash_map->buckets[slot] = e;
139 } else { 146 } else {
140 prev->next = e; 147 prev->next = e;
141 } 148 }
142 e->next = elm; 149 e->next = elm;
150 elm = e;
143 151
144 // increase the size 152 // increase the size
145 map->collection.size++; 153 map->collection.size++;
146 } 154 }
147 155
148 return 0; 156 // return pointer to the element
157 return elm->data;
149 } 158 }
150 159
151 static void cx_hash_map_unlink( 160 static void cx_hash_map_unlink(
152 struct cx_hash_map_s *hash_map, 161 struct cx_hash_map_s *hash_map,
153 size_t slot, 162 size_t slot,

mercurial