1 /*
2 * Copyright (C) 2021 Jakub Kruszona-Zawadzki, Core Technology Sp. z o.o.
3 *
4 * This file is part of MooseFS.
5 *
6 * MooseFS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, version 2 (only).
9 *
10 * MooseFS is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with MooseFS; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA
18 * or visit http://www.gnu.org/licenses/gpl-2.0.html
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stddef.h>
28 #include <inttypes.h>
29 #ifdef HAVE_SYS_MMAN_H
30 #include <sys/mman.h>
31 #endif
32
33 #include "massert.h"
34
35 #include "glue.h"
36
37 typedef struct _dictentry {
38 struct _dictentry *next;
39 uint32_t hashval;
40 uint32_t refcnt;
41 uint32_t leng;
42 const uint8_t data[1];
43 } dictentry;
44
45 #define LOHASH_BITS 20
46 #define ENTRY_TYPE dictentry
47 #define GLUE_FN_NAME_PREFIX(Y) GLUE(dict,Y)
48 #define HASH_ARGS_TYPE_LIST const uint8_t *data,uint32_t leng
49 #define HASH_ARGS_LIST data,leng
50 #define GLUE_HASH_TAB_PREFIX(Y) GLUE(dict,Y)
51 #define HASH_VALUE_FIELD hashval
52
GLUE_FN_NAME_PREFIX(_cmp)53 static inline int GLUE_FN_NAME_PREFIX(_cmp)(ENTRY_TYPE *e,HASH_ARGS_TYPE_LIST) {
54 return (e->leng==leng && memcmp((char*)(e->data),(char*)data,leng)==0);
55 }
56
GLUE_FN_NAME_PREFIX(_hash)57 static inline uint32_t GLUE_FN_NAME_PREFIX(_hash)(HASH_ARGS_TYPE_LIST) {
58 uint32_t hash,i;
59 hash = leng;
60 for (i=0 ; i<leng ; i++) {
61 hash = hash*33+data[i];
62 }
63 return hash;
64 }
65
66 // GLUE_FN_NAME_PREFIX(_ehash) is needed only if HASH_VALUE_FIELD is not defined !!!
67
68 #include "hash_begin.h"
69
70 /* externals */
71
dict_init(void)72 int dict_init(void) {
73 dict_hash_init();
74 return 0;
75 }
76
dict_cleanup(void)77 void dict_cleanup(void) {
78 dict_hash_cleanup();
79 }
80
dict_search(const uint8_t * data,uint32_t leng)81 void* dict_search(const uint8_t *data,uint32_t leng) {
82 return dict_find(data,leng);
83 }
84
dict_insert(const uint8_t * data,uint32_t leng)85 void* dict_insert(const uint8_t *data,uint32_t leng) {
86 dictentry *de;
87 de = dict_find(data,leng);
88 if (de) {
89 de->refcnt++;
90 return de;
91 }
92 de = malloc(offsetof(dictentry,data)+leng);
93 passert(de);
94 de->refcnt = 1;
95 de->leng = leng;
96 memcpy((uint8_t*)(de->data),data,leng);
97 dict_add(de);
98 return de;
99 }
100
dict_get_ptr(void * dptr)101 const uint8_t* dict_get_ptr(void *dptr) {
102 dictentry *de = (dictentry*)dptr;
103
104 return de->data;
105 }
106
dict_get_leng(void * dptr)107 uint32_t dict_get_leng(void *dptr) {
108 dictentry *de = (dictentry*)dptr;
109
110 return de->leng;
111 }
112
dict_get_hash(void * dptr)113 uint32_t dict_get_hash(void *dptr) {
114 dictentry *de = (dictentry*)dptr;
115
116 return de->hashval;
117 }
118
dict_dec_ref(void * dptr)119 void dict_dec_ref(void *dptr) {
120 dictentry *de = (dictentry*)dptr;
121 massert(de->refcnt>0,"dictionary reference counter is zero");
122 de->refcnt--;
123 if (de->refcnt==0) {
124 dict_delete(de);
125 free(de);
126 }
127 }
128
dict_inc_ref(void * dptr)129 void dict_inc_ref(void *dptr) {
130 dictentry *de = (dictentry*)dptr;
131 massert(de->refcnt>0,"dictionary reference counter is zero");
132 de->refcnt++;
133 }
134
135 #include "hash_end.h"
136
137 #undef LOHASH_BITS
138 #undef ENTRY_TYPE
139 #undef GLUE_FN_NAME_PREFIX
140 #undef HASH_ARGS_TYPE_LIST
141 #undef HASH_ARGS_LIST
142 #undef GLUE_HASH_TAB_PREFIX
143