Main Page
Modules
Data Structures
Files
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
modules
common
src
include
citrusleaf
src/include/citrusleaf/cf_shash.h
Go to the documentation of this file.
1
/******************************************************************************
2
* Copyright 2008-2013 by Aerospike.
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a copy
5
* of this software and associated documentation files (the "Software"), to
6
* deal in the Software without restriction, including without limitation the
7
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
* sell copies of the Software, and to permit persons to whom the Software is
9
* furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice shall be included in
12
* all copies or substantial portions of the Software.
13
*
14
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
* IN THE SOFTWARE.
21
*****************************************************************************/
22
#pragma once
23
24
/*
25
* A general purpose hashtable implementation
26
* Uses locks, so only moderately fast
27
* Just, hopefully, the last hash table you'll ever need
28
* And you can keep adding cool things to it
29
*/
30
31
#include <pthread.h>
32
#include <stdbool.h>
33
#include <stddef.h>
34
#include <stdint.h>
35
36
#include <citrusleaf/cf_types.h>
37
38
#ifdef __cplusplus
39
extern
"C"
{
40
#endif
41
42
/******************************************************************************
43
* CONSTANTS
44
******************************************************************************/
45
46
#define SHASH_ERR_FOUND -4
47
#define SHASH_ERR_NOTFOUND -3
48
#define SHASH_ERR_BUFSZ -2
49
#define SHASH_ERR -1
50
#define SHASH_OK 0
51
52
/**
53
* support resizes (will sometimes hang for long periods)
54
*/
55
#define SHASH_CR_RESIZE 0x01
56
57
/**
58
* support 'grab' call (requires more memory)
59
*/
60
#define SHASH_CR_GRAB 0x02
61
62
/**
63
* support multithreaded access with a single big lock
64
*/
65
#define SHASH_CR_MT_BIGLOCK 0x04
66
67
/**
68
* support multithreaded access with a pool of object loccks
69
*/
70
#define SHASH_CR_MT_MANYLOCK 0x08
71
72
/**
73
* Do not track memory allocations in this hash table.
74
* (Used only when creating the hash table tracking memory allocations....)
75
*/
76
#define SHASH_CR_UNTRACKED 0x10
77
78
/**
79
* indicate that a delete should be done during the reduction
80
*/
81
#define SHASH_REDUCE_DELETE (1)
82
83
/******************************************************************************
84
* TYPES
85
******************************************************************************/
86
87
/**
88
* A generic call for hash functions the user can create
89
*/
90
typedef
uint32_t (*
shash_hash_fn
) (
void
*
key
);
91
92
/**
93
* Type for a function to be called under the hash table locks to atomically update a hash table entry.
94
* The old value is the current value of the key, or NULL if non-existent.
95
* The new value is allocated by the caller.
96
* User data can be anything.
97
*/
98
typedef
void (*
shash_update_fn
) (
void
*
key
,
void
*value_old,
void
*value_new,
void
*udata);
99
100
/**
101
* Typedef for a "reduce" fuction that is called on every node
102
* (Note about return value: some kinds of reduces can manipulate the hash table,
103
* allowing deletion. See the particulars of the reduce call.)
104
*/
105
typedef
int (*
shash_reduce_fn
) (
void
*
key
,
void
*
data
,
void
*udata);
106
107
/**
108
* Simple (and slow) element is when
109
* everything is variable (although a very nicely packed structure for 32 or 64
110
*/
111
struct
shash_elem_s
{
112
struct
shash_elem_s
*
next
;
113
bool
in_use
;
114
uint8_t data[];
// key_len bytes of key, value_len bytes of value
115
};
116
117
typedef
struct
shash_elem_s
shash_elem;
118
119
struct
shash_s
{
120
uint
elements
;
// INVALID in manylocks case - see notes under get_size
121
uint32_t
key_len
;
122
uint32_t
value_len
;
123
uint
flags
;
124
shash_hash_fn
h_fn
;
125
uint
table_len
;
// number of elements currently in the table
126
void
*
table
;
127
pthread_mutex_t
biglock
;
128
pthread_mutex_t *
lock_table
;
129
};
130
131
typedef
struct
shash_s
shash;
132
133
/******************************************************************************
134
* FUNCTIONS
135
******************************************************************************/
136
137
/**
138
* Create a hash table
139
* Pass in the hash function (required)
140
* the key length if static (if not static pass 0
141
* the value length if static (if not static pass 0
142
* The initial table size
143
* a set of flags
144
*/
145
int
shash_create
(shash **h,
shash_hash_fn
h_fn
, uint32_t
key_len
, uint32_t
value_len
, uint32_t
sz
,
uint
flags
);
146
147
/**
148
* Place a value into the hash
149
* Value will be copied into the hash
150
*/
151
int
shash_put
(shash *h,
void
*key,
void
*value);
152
153
/**
154
* Place a unique value into the hash
155
* Value will be copied into the hash
156
*/
157
int
shash_put_unique
(shash *h,
void
*key,
void
*value);
158
159
/**
160
* Place a duplicate value into the hash
161
* Value will be copied into the hash
162
*/
163
int
shash_put_duplicate
(shash *h,
void
*key,
void
*value);
164
165
/**
166
* call with the buffer you want filled; if you just want to check for
167
* existence, call with value set to NULL
168
*/
169
int
shash_get
(shash *h,
void
*key,
void
*value);
170
171
/**
172
* Returns the pointer to the internal item, and a locked-lock
173
* which allows the touching of internal state. If non-lock hash table,
174
* vlock param will be ignored
175
*
176
* Note that the vlock is passed back only when the return code is BB_OK.
177
* In the case where nothing is found, no lock is held.
178
* It might be better to do it the other way, but you can change it later if you want
179
*/
180
int
shash_get_vlock
(shash *h,
void
*key,
void
**value,pthread_mutex_t **vlock);
181
182
/**
183
* Does a get and delete at the same time so you can make sure only one person
184
* gets what was inserted
185
*/
186
int
shash_get_and_delete
(shash *h,
void
*key,
void
*value);
187
188
/**
189
* Atomically update an entry in the hash table using a user-supplied update function and user data.
190
* The update function performs the merge of the old and new values, with respect to the user data
191
* and returns the new value.
192
*/
193
int
shash_update
(shash *h,
void
*key,
void
*value_old,
void
*value_new,
shash_update_fn
update_fn,
void
*udata);
194
195
/**
196
* Got a key you want removed - this is the function to call
197
*/
198
int
shash_delete
(shash *h,
void
*key);
199
200
/**
201
* Special function you can call when you already have the lock - such as
202
* a vlock get
203
*/
204
int
shash_delete_lockfree
(shash *h,
void
*key);
205
206
/**
207
* Get the number of elements currently in the hash
208
*/
209
uint32_t
shash_get_size
(shash *h);
210
211
/**
212
* An interesting idea: readv / writev for these functions?
213
*/
214
215
/**
216
* Find / get a value from the hash
217
* But take the reference count on the object; must be returned with the
218
* return call
219
*/
220
int
shash_grab
(shash *h,
void
*key, uint32_t
key_len
,
void
**value, uint32_t *
value_len
);
221
222
/**
223
* Return a value that has been gotten
224
*/
225
int
shash_return
(shash *h,
void
*value);
226
227
/**
228
* Map/Reduce pattern - call the callback on every element in the hash
229
* Warning: the entire traversal can hold the lock in the 'biglock' case,
230
* so make the reduce_fn lightweight! Consider queuing or soemthing if you
231
* want to do something fancy
232
*/
233
int
shash_reduce
(shash *h,
shash_reduce_fn
reduce_fn,
void
*udata);
234
235
/**
236
* Map/Reduce pattern - call the callback on every element in the hash
237
* This instance allows deletion of hash elements during the reduce:
238
* return -1 to cause the deletion of the element visisted
239
*/
240
int
shash_reduce_delete
(shash *h,
shash_reduce_fn
reduce_fn,
void
*udata);
241
242
/**
243
* Delete all the data from the entire hash - complete cleanup
244
*/
245
void
shash_deleteall_lockfree
(shash *h);
246
247
/**
248
* Destroy the entire hash - all memory will be freed
249
*/
250
void
shash_destroy
(shash *h);
251
252
/******************************************************************************
253
* MACROS
254
******************************************************************************/
255
256
#define SHASH_ELEM_KEY_PTR(_h, _e) ( (void *) _e->data )
257
#define SHASH_ELEM_VALUE_PTR(_h, _e) ( (void *) (_e->data + _h->key_len) )
258
#define SHASH_ELEM_SZ(_h) ( sizeof(shash_elem) + (_h->key_len) + (_h->value_len) )
259
260
/******************************************************************************/
261
262
#ifdef __cplusplus
263
}
// end extern "C"
264
#endif