14 #define _XOPEN_SOURCE 700
21 #include <sys/types.h>
30 #include "sion_error_handler.h"
36 KEYVALUE_TABLE_ENTRY_STATE_USED,
37 KEYVALUE_TABLE_ENTRY_STATE_FREE,
38 KEYVALUE_TABLE_ENTRY_STATE_UNKNOWN
39 } sion_keyvalue_table_entry_state_t;
46 int num_added_entries;
49 int iterator_lastreadindex;
61 sion_keyvalue_table_entry_state_t state;
68 #define HASH_FCT_SIMPLE_not
69 #define HASH_FCT_SPLIT
71 #define DFUNCTION "_sion_keyvalue_table_hash_fct"
72 unsigned int _sion_keyvalue_table_hash_fct(sion_table_key_t key,
int tab_size) {
75 #if defined(HASH_FCT_SIMPLE)
78 index = (
unsigned int) key % tab_size;
80 #elif defined(HASH_FCT_SPLIT)
83 uint32_t upper =( uint32_t) (key >> 32);
84 uint32_t lower =( uint32_t) (key & 0xffffffff);
85 DPRINTFP((2, DFUNCTION, -1,
"key %ld -> %d %d \n",(
long) key, (
int) upper, (
int) lower));
86 index = (
unsigned int) (
87 (
unsigned int) upper % tab_size
88 + (
unsigned int) lower % tab_size
97 #define DFUNCTION "_sion_keyvalue_table_init"
103 DPRINTFP((2, DFUNCTION, -1,
"enter init size=%d\n",size));
107 _sion_errorprint(0,_SION_ERROR_RETURN,
"cannot allocate internal keyvalue table of size %lu , aborting ...\n", (
unsigned long)
sizeof(
_sion_keyvalue_table));
112 if (entries == NULL) {
113 _sion_errorprint(0,_SION_ERROR_RETURN,
"cannot allocate internal keyvalue table entries of size %lu , aborting ...\n", (
unsigned long) size);
117 table->entries=entries;
121 table->num_added_entries=0;
122 table->iterator_lastreadindex=-1;
123 table->iterator_lastreadentry=NULL;
124 table->iterator_next=NULL;
125 table->iterator_head=NULL;
126 table->iterator_tail=NULL;
127 for(i=0;i<table->size;i++) {
128 table->entries[i].state=KEYVALUE_TABLE_ENTRY_STATE_FREE;
129 table->entries[i].key=0;
130 table->entries[i].iterator_next=NULL;
131 table->entries[i].next=NULL;
132 table->entries[i].data=NULL;
136 DPRINTFP((2, DFUNCTION, -1,
"leave\n"));
141 #define DFUNCTION "_sion_keyvalue_table_destroy"
143 size_t rc=SION_SUCCESS;
147 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
148 if((*table)->entries) {
151 for(i=0;i<(*table)->size;i++) {
153 if(((*table)->entries[i].state!=KEYVALUE_TABLE_ENTRY_STATE_FREE) && ((*table)->entries[i].data!=NULL)) {
154 _SION_SAFE_FREE((*table)->entries[i].data, NULL);
157 entry=(*table)->entries[i].next;
158 while (entry != NULL) {
159 if((entry->state!=KEYVALUE_TABLE_ENTRY_STATE_FREE) && (entry->data!=NULL)) {
160 _SION_SAFE_FREE(entry->data, NULL);
162 next_entry=entry->next;
163 _SION_SAFE_FREE(entry, NULL);
168 free((*table)->entries);
169 (*table)->entries=NULL;
175 DPRINTFP((2, DFUNCTION, -1,
"leave rc=%d\n",rc));
180 #define DFUNCTION "_sion_keyvalue_table_store"
182 size_t rc=SION_SUCCESS;
186 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
188 index = _sion_keyvalue_table_hash_fct(key,table->size);
189 DPRINTFP((2, DFUNCTION, -1,
"store entry with key %ld index=%d\n", (
long) key, index));
191 new_entry = &table->entries[index];
192 if (new_entry->state != KEYVALUE_TABLE_ENTRY_STATE_FREE) {
193 while (new_entry->next != NULL) {
194 new_entry = new_entry->next;
197 if (new_entry->next == NULL) {
198 return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,
"cannot allocate internal keyvalue table entry, aborting ...\n"));
200 DPRINTFP((2, DFUNCTION, -1,
"add new entry to next list\n"));
201 table->num_added_entries++;
202 new_entry = new_entry->next;
206 new_entry->state= KEYVALUE_TABLE_ENTRY_STATE_USED;
207 new_entry->key = key;
208 new_entry->data = data;
209 new_entry->next = NULL;
210 new_entry->iterator_next = NULL;
212 if ( (table->iterator_head==NULL) && (table->iterator_tail==NULL) ) {
214 table->iterator_next=table->iterator_head=table->iterator_tail=new_entry;
216 table->iterator_tail->iterator_next=new_entry;
217 table->iterator_tail=table->iterator_tail->iterator_next;
221 DPRINTFP((2, DFUNCTION, -1,
"new entry successfully added (key %ld index=%d)\n", (
long) key, index));
222 DPRINTFP((2, DFUNCTION, -1,
"TABLE[slots %d of %d, +%d, total %d] \n", table->used - table->num_added_entries,table->size,table->num_added_entries,table->used));
224 DPRINTFP((2, DFUNCTION, -1,
"leave rc=%d\n",rc));
229 #define DFUNCTION "_sion_keyvalue_table_lookup"
234 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
236 index = _sion_keyvalue_table_hash_fct(key,table->size);
237 DPRINTFP((2, DFUNCTION, -1,
"lookup entry with key %ld index=%d\n", (
long) key, index));
239 entry = &(table->entries[index]);
240 while (entry != NULL) {
242 DPRINTFP((2, DFUNCTION, -1,
"search: state=%ld\n",(
long) entry->state ));
244 if (entry->state == KEYVALUE_TABLE_ENTRY_STATE_USED) {
245 if(entry->key == key) {
246 DPRINTFP((2, DFUNCTION, -1,
"key found %ld in key list\n",(
long) entry->key ));
249 DPRINTFP((2, DFUNCTION, -1,
"skip this key another key found %ld in list\n",(
long) entry->key ));
257 DPRINTFP((2, DFUNCTION, -1,
"leave:entry not found\n"));
263 #define DFUNCTION "_sion_keyvalue_table_iterator_reset"
268 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
269 table->iterator_lastreadindex=-1;
270 table->iterator_lastreadentry=NULL;
271 table->iterator_next=table->iterator_head;
272 DPRINTFP((2, DFUNCTION, -1,
"leave\n"));
278 #define DFUNCTION "_sion_keyvalue_table_iterator_next_in_store_order"
279 int _sion_keyvalue_table_iterator_next_in_store_order(
_sion_keyvalue_table* table, sion_table_key_t *key,
void **data) {
282 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
284 return(SION_NOT_SUCCESS);
286 entry=table->iterator_next;
291 DPRINTFP((2, DFUNCTION, -1,
"found entry with key %ld\n",(
long) *key));
292 table->iterator_next=entry->iterator_next;
293 return(SION_SUCCESS);
295 return(SION_NOT_SUCCESS);
300 #define DFUNCTION "_sion_keyvalue_table_iterator_next"
301 int _sion_keyvalue_table_iterator_next(
_sion_keyvalue_table* table, sion_table_key_t *key,
void **data) {
303 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
305 return(SION_NOT_SUCCESS);
307 if(table->iterator_lastreadindex==-1) {
309 DPRINTFP((2, DFUNCTION, -1,
"start first\n"));
310 table->iterator_lastreadindex++;
311 while(table->iterator_lastreadindex < table->size) {
312 if (table->entries[table->iterator_lastreadindex].state == KEYVALUE_TABLE_ENTRY_STATE_USED) {
313 table->iterator_lastreadentry = &table->entries[table->iterator_lastreadindex];
316 table->iterator_lastreadindex++;
318 DPRINTFP((2, DFUNCTION, -1,
"start first, found entry at index %d\n",table->iterator_lastreadindex));
323 if(table->iterator_lastreadentry->next != NULL) {
324 table->iterator_lastreadentry=table->iterator_lastreadentry->next;
325 DPRINTFP((2, DFUNCTION, -1,
"found another entry in list at index %d\n",table->iterator_lastreadindex));
328 table->iterator_lastreadindex++;
329 while(table->iterator_lastreadindex < table->size) {
330 if (table->entries[table->iterator_lastreadindex].state == KEYVALUE_TABLE_ENTRY_STATE_USED) {
331 table->iterator_lastreadentry = &table->entries[table->iterator_lastreadindex];
332 DPRINTFP((2, DFUNCTION, -1,
"found entry at another index %d\n",table->iterator_lastreadindex));
335 table->iterator_lastreadindex++;
339 if(table->iterator_lastreadindex < table->size) {
340 *key=table->iterator_lastreadentry->key;
341 *data=table->iterator_lastreadentry->data;
342 DPRINTFP((2, DFUNCTION, -1,
"leave: entry found\n"));
343 return(SION_SUCCESS);
345 DPRINTFP((2, DFUNCTION, -1,
"leave: next entry not found\n"));
346 return(SION_NOT_SUCCESS);
351 #define DFUNCTION "_sion_keyvalue_table_get_size"
353 size_t help_bytes, bytes=0;
357 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
360 DPRINTFP((2, DFUNCTION, -1,
" sizeof key_table= %5d\n", help_bytes));
366 DPRINTFP((2, DFUNCTION, -1,
" sizeof key_entries= %5d\n", help_bytes));
370 for(i=0;i<table->size;i++) {
371 entry=table->entries[i].next;
372 while (entry != NULL) {
378 DPRINTFP((2, DFUNCTION, -1,
" sizeof key_addentries= %5d\n", help_bytes));
383 DPRINTFP((2, DFUNCTION, -1,
"leave bytes=%d\n",bytes));