]> pd.if.org Git - nbds/blob - map/map.c
a8a7068c6e88f3e208dc758b250a624d2f849447
[nbds] / map / map.c
1 /* 
2  * Written by Josh Dybnis and released to the public domain, as explained at
3  * http://creativecommons.org/licenses/publicdomain
4  *
5  * generic interface for map-like data structures
6  */
7
8 #include "common.h"
9 #include "mlocal.h"
10 #include "mem.h"
11 #include "map.h"
12
13 struct map {
14     map_type_e type;
15     void *impl;
16 };
17
18 map_t *map_alloc (map_type_e map_type) {
19     void *impl = NULL;
20     switch (map_type) {
21         case MAP_TYPE_HASHTABLE: impl = ht_alloc(); break;
22         case MAP_TYPE_SKIPLIST:  impl = sl_alloc(); break;
23         case MAP_TYPE_LIST:      impl = ll_alloc(); break;
24     }
25     map_t *map = NULL;
26     if (impl) {
27         map = nbd_malloc(sizeof(map_t));
28         map->type = map_type;
29         map->impl = impl;
30     }
31     return map;
32 }
33
34 void map_free (map_t *map) {
35     switch (map->type) {
36         case MAP_TYPE_HASHTABLE: ht_free(map->impl); break;
37         case MAP_TYPE_SKIPLIST:  sl_free(map->impl); break;
38         case MAP_TYPE_LIST:      ll_free(map->impl); break;
39     }
40 }
41
42 void map_print (map_t *map) {
43     switch (map->type) {
44         case MAP_TYPE_HASHTABLE: ht_print(map->impl); break;
45         case MAP_TYPE_SKIPLIST:  sl_print(map->impl); break;
46         case MAP_TYPE_LIST:      ll_print(map->impl); break;
47     }
48 }
49
50 uint64_t map_stat (map_t *map, map_stat_e stat_type) {
51     switch (stat_type) {
52         case MAP_STAT_COUNT: 
53             if (map->type != MAP_TYPE_HASHTABLE)
54                 return ERROR_UNSUPPORTED_FEATURE;
55             return ht_count(map->impl);
56     }
57     return ERROR_INVALID_OPTION;
58 }
59
60 uint64_t map_get (map_t *map, const void *key_data, uint32_t key_len) {
61     switch (map->type) {
62         case MAP_TYPE_HASHTABLE: return ht_get(map->impl, key_data, key_len);
63         case MAP_TYPE_SKIPLIST:  return sl_lookup(map->impl, key_data, key_len);
64         case MAP_TYPE_LIST:      return ll_lookup(map->impl, key_data, key_len);
65     }
66     return ERROR_INVALID_ARGUMENT;
67 }
68
69 uint64_t map_set (map_t *map, const void *key_data, uint32_t key_len, uint64_t new_val) {
70     switch (map->type) {
71         case MAP_TYPE_HASHTABLE: return ht_cas(map->impl, key_data, key_len, CAS_EXPECT_WHATEVER, new_val);
72         case MAP_TYPE_SKIPLIST:  return sl_cas(map->impl, key_data, key_len, CAS_EXPECT_WHATEVER, new_val);
73         case MAP_TYPE_LIST:      return ll_cas(map->impl, key_data, key_len, CAS_EXPECT_WHATEVER, new_val);
74     }
75     return ERROR_INVALID_ARGUMENT;
76 }
77
78 uint64_t map_add (map_t *map, const void *key_data, uint32_t key_len, uint64_t new_val) {
79     switch (map->type) {
80         case MAP_TYPE_HASHTABLE: return ht_cas(map->impl, key_data, key_len, CAS_EXPECT_DOES_NOT_EXIST, new_val);
81         case MAP_TYPE_SKIPLIST:  return sl_cas(map->impl, key_data, key_len, CAS_EXPECT_DOES_NOT_EXIST, new_val);
82         case MAP_TYPE_LIST:      return ll_cas(map->impl, key_data, key_len, CAS_EXPECT_DOES_NOT_EXIST, new_val);
83     }
84     return ERROR_INVALID_ARGUMENT;
85 }
86
87 uint64_t map_cas (map_t *map, const void *key_data, uint32_t key_len, uint64_t expected_val, uint64_t new_val) {
88     switch (map->type) {
89         case MAP_TYPE_HASHTABLE: return ht_cas(map->impl, key_data, key_len, expected_val, new_val);
90         case MAP_TYPE_SKIPLIST:  return sl_cas(map->impl, key_data, key_len, expected_val, new_val);
91         case MAP_TYPE_LIST:      return ll_cas(map->impl, key_data, key_len, expected_val, new_val);
92     }
93     return ERROR_INVALID_ARGUMENT;
94 }
95
96 uint64_t map_replace(map_t *map, const void *key_data, uint32_t key_len, uint64_t new_val) {
97     switch (map->type) {
98         case MAP_TYPE_HASHTABLE: return ht_cas(map->impl, key_data, key_len, CAS_EXPECT_EXISTS, new_val);
99         case MAP_TYPE_SKIPLIST:  return sl_cas(map->impl, key_data, key_len, CAS_EXPECT_EXISTS, new_val);
100         case MAP_TYPE_LIST:      return ll_cas(map->impl, key_data, key_len, CAS_EXPECT_EXISTS, new_val);
101     }
102     return ERROR_INVALID_ARGUMENT;
103 }
104
105 uint64_t map_remove (map_t *map, const void *key_data, uint32_t key_len) {
106     switch (map->type) {
107         case MAP_TYPE_HASHTABLE: return ht_remove(map->impl, key_data, key_len);
108         case MAP_TYPE_SKIPLIST:  return sl_remove(map->impl, key_data, key_len);
109         case MAP_TYPE_LIST:      return ll_remove(map->impl, key_data, key_len);
110     }
111     return ERROR_INVALID_ARGUMENT;
112 }