19 #include <sys/types.h> 28 #include "sion_error_handler.h" 34 KEYVALUE_TABLE_ENTRY_STATE_USED,
35 KEYVALUE_TABLE_ENTRY_STATE_FREE,
36 KEYVALUE_TABLE_ENTRY_STATE_UNKNOWN
37 } sion_keyvalue_table_entry_state_t;
44 int num_added_entries;
47 int iterator_lastreadindex;
59 sion_keyvalue_table_entry_state_t state;
66 #define HASH_FCT_SIMPLE_not 67 #define HASH_FCT_SPLIT 69 #define DFUNCTION "_sion_keyvalue_table_hash_fct" 70 unsigned int _sion_keyvalue_table_hash_fct(sion_table_key_t key,
int tab_size) {
73 #if defined(HASH_FCT_SIMPLE) 76 index = (
unsigned int) key % tab_size;
78 #elif defined(HASH_FCT_SPLIT) 81 uint32_t upper =( uint32_t) (key >> 32);
82 uint32_t lower =( uint32_t) (key & 0xffffffff);
83 DPRINTFP((2, DFUNCTION, -1,
"key %ld -> %d %d \n",(
long) key, (
int) upper, (
int) lower));
84 index = (
unsigned int) (
85 (
unsigned int) upper % tab_size
86 + (
unsigned int) lower % tab_size
95 #define DFUNCTION "_sion_keyvalue_table_init" 101 DPRINTFP((2, DFUNCTION, -1,
"enter init size=%d\n",size));
105 _sion_errorprint(0,_SION_ERROR_RETURN,
"cannot allocate internal keyvalue table of size %lu , aborting ...\n", (
unsigned long)
sizeof(
_sion_keyvalue_table));
110 if (entries == NULL) {
111 _sion_errorprint(0,_SION_ERROR_RETURN,
"cannot allocate internal keyvalue table entries of size %lu , aborting ...\n", (
unsigned long) size);
115 table->entries=entries;
119 table->num_added_entries=0;
120 table->iterator_lastreadindex=-1;
121 table->iterator_lastreadentry=NULL;
122 table->iterator_next=NULL;
123 table->iterator_head=NULL;
124 table->iterator_tail=NULL;
125 for(i=0;i<table->size;i++) {
126 table->entries[i].state=KEYVALUE_TABLE_ENTRY_STATE_FREE;
127 table->entries[i].key=0;
128 table->entries[i].iterator_next=NULL;
129 table->entries[i].next=NULL;
130 table->entries[i].data=NULL;
134 DPRINTFP((2, DFUNCTION, -1,
"leave\n"));
139 #define DFUNCTION "_sion_keyvalue_table_destroy" 141 size_t rc=SION_SUCCESS;
145 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
146 if((*table)->entries) {
149 for(i=0;i<(*table)->size;i++) {
151 if(((*table)->entries[i].state!=KEYVALUE_TABLE_ENTRY_STATE_FREE) && ((*table)->entries[i].data!=NULL)) {
152 _SION_SAFE_FREE((*table)->entries[i].data, NULL);
155 entry=(*table)->entries[i].next;
156 while (entry != NULL) {
157 if((entry->state!=KEYVALUE_TABLE_ENTRY_STATE_FREE) && (entry->data!=NULL)) {
158 _SION_SAFE_FREE(entry->data, NULL);
160 next_entry=entry->next;
161 _SION_SAFE_FREE(entry, NULL);
166 free((*table)->entries);
167 (*table)->entries=NULL;
173 DPRINTFP((2, DFUNCTION, -1,
"leave rc=%d\n",rc));
178 #define DFUNCTION "_sion_keyvalue_table_store" 180 size_t rc=SION_SUCCESS;
184 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
186 index = _sion_keyvalue_table_hash_fct(key,table->size);
187 DPRINTFP((2, DFUNCTION, -1,
"store entry with key %ld index=%d\n", (
long) key, index));
189 new_entry = &table->entries[index];
190 if (new_entry->state != KEYVALUE_TABLE_ENTRY_STATE_FREE) {
191 while (new_entry->next != NULL) {
192 new_entry = new_entry->next;
195 if (new_entry->next == NULL) {
196 return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,
"cannot allocate internal keyvalue table entry, aborting ...\n"));
198 DPRINTFP((2, DFUNCTION, -1,
"add new entry to next list\n"));
199 table->num_added_entries++;
200 new_entry = new_entry->next;
204 new_entry->state= KEYVALUE_TABLE_ENTRY_STATE_USED;
205 new_entry->key = key;
206 new_entry->data = data;
207 new_entry->next = NULL;
208 new_entry->iterator_next = NULL;
210 if ( (table->iterator_head==NULL) && (table->iterator_tail==NULL) ) {
212 table->iterator_next=table->iterator_head=table->iterator_tail=new_entry;
214 table->iterator_tail->iterator_next=new_entry;
215 table->iterator_tail=table->iterator_tail->iterator_next;
219 DPRINTFP((2, DFUNCTION, -1,
"new entry successfully added (key %ld index=%d)\n", (
long) key, index));
220 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));
222 DPRINTFP((2, DFUNCTION, -1,
"leave rc=%d\n",rc));
227 #define DFUNCTION "_sion_keyvalue_table_lookup" 232 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
234 index = _sion_keyvalue_table_hash_fct(key,table->size);
235 DPRINTFP((2, DFUNCTION, -1,
"lookup entry with key %ld index=%d\n", (
long) key, index));
237 entry = &(table->entries[index]);
238 while (entry != NULL) {
240 DPRINTFP((2, DFUNCTION, -1,
"search: state=%ld\n",(
long) entry->state ));
242 if (entry->state == KEYVALUE_TABLE_ENTRY_STATE_USED) {
243 if(entry->key == key) {
244 DPRINTFP((2, DFUNCTION, -1,
"key found %ld in key list\n",(
long) entry->key ));
247 DPRINTFP((2, DFUNCTION, -1,
"skip this key another key found %ld in list\n",(
long) entry->key ));
255 DPRINTFP((2, DFUNCTION, -1,
"leave:entry not found\n"));
261 #define DFUNCTION "_sion_keyvalue_table_iterator_reset" 266 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
267 table->iterator_lastreadindex=-1;
268 table->iterator_lastreadentry=NULL;
269 table->iterator_next=table->iterator_head;
270 DPRINTFP((2, DFUNCTION, -1,
"leave\n"));
276 #define DFUNCTION "_sion_keyvalue_table_iterator_next_in_store_order" 277 int _sion_keyvalue_table_iterator_next_in_store_order(
_sion_keyvalue_table* table, sion_table_key_t *key,
void **data) {
280 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
282 return(SION_NOT_SUCCESS);
284 entry=table->iterator_next;
289 DPRINTFP((2, DFUNCTION, -1,
"found entry with key %ld\n",(
long) *key));
290 table->iterator_next=entry->iterator_next;
291 return(SION_SUCCESS);
293 return(SION_NOT_SUCCESS);
298 #define DFUNCTION "_sion_keyvalue_table_iterator_next" 299 int _sion_keyvalue_table_iterator_next(
_sion_keyvalue_table* table, sion_table_key_t *key,
void **data) {
301 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
303 return(SION_NOT_SUCCESS);
305 if(table->iterator_lastreadindex==-1) {
307 DPRINTFP((2, DFUNCTION, -1,
"start first\n"));
308 table->iterator_lastreadindex++;
309 while(table->iterator_lastreadindex < table->size) {
310 if (table->entries[table->iterator_lastreadindex].state == KEYVALUE_TABLE_ENTRY_STATE_USED) {
311 table->iterator_lastreadentry = &table->entries[table->iterator_lastreadindex];
314 table->iterator_lastreadindex++;
316 DPRINTFP((2, DFUNCTION, -1,
"start first, found entry at index %d\n",table->iterator_lastreadindex));
321 if(table->iterator_lastreadentry->next != NULL) {
322 table->iterator_lastreadentry=table->iterator_lastreadentry->next;
323 DPRINTFP((2, DFUNCTION, -1,
"found another entry in list at index %d\n",table->iterator_lastreadindex));
326 table->iterator_lastreadindex++;
327 while(table->iterator_lastreadindex < table->size) {
328 if (table->entries[table->iterator_lastreadindex].state == KEYVALUE_TABLE_ENTRY_STATE_USED) {
329 table->iterator_lastreadentry = &table->entries[table->iterator_lastreadindex];
330 DPRINTFP((2, DFUNCTION, -1,
"found entry at another index %d\n",table->iterator_lastreadindex));
333 table->iterator_lastreadindex++;
337 if(table->iterator_lastreadindex < table->size) {
338 *key=table->iterator_lastreadentry->key;
339 *data=table->iterator_lastreadentry->data;
340 DPRINTFP((2, DFUNCTION, -1,
"leave: entry found\n"));
341 return(SION_SUCCESS);
343 DPRINTFP((2, DFUNCTION, -1,
"leave: next entry not found\n"));
344 return(SION_NOT_SUCCESS);
349 #define DFUNCTION "_sion_keyvalue_table_get_size" 351 size_t help_bytes, bytes=0;
355 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
358 DPRINTFP((2, DFUNCTION, -1,
" sizeof key_table= %5d\n", help_bytes));
364 DPRINTFP((2, DFUNCTION, -1,
" sizeof key_entries= %5d\n", help_bytes));
368 for(i=0;i<table->size;i++) {
369 entry=table->entries[i].next;
370 while (entry != NULL) {
376 DPRINTFP((2, DFUNCTION, -1,
" sizeof key_addentries= %5d\n", help_bytes));
381 DPRINTFP((2, DFUNCTION, -1,
"leave bytes=%d\n",bytes));