19 #include <sys/types.h> 33 KEYVALUE_TABLE_ENTRY_STATE_USED,
34 KEYVALUE_TABLE_ENTRY_STATE_FREE,
35 KEYVALUE_TABLE_ENTRY_STATE_UNKNOWN
36 } sion_keyvalue_table_entry_state_t;
43 int num_added_entries;
46 int iterator_lastreadindex;
58 sion_keyvalue_table_entry_state_t state;
65 #define HASH_FCT_SIMPLE_not 66 #define HASH_FCT_SPLIT 68 #define DFUNCTION "_sion_keyvalue_table_hash_fct" 69 unsigned int _sion_keyvalue_table_hash_fct(sion_table_key_t key,
int tab_size) {
72 #if defined(HASH_FCT_SIMPLE) 75 index = (
unsigned int) key % tab_size;
77 #elif defined(HASH_FCT_SPLIT) 80 uint32_t upper =( uint32_t) (key >> 32);
81 uint32_t lower =( uint32_t) (key & 0xffffffff);
82 DPRINTFP((2, DFUNCTION, -1,
"key %ld -> %d %d \n",(
long) key, (
int) upper, (
int) lower));
83 index = (
unsigned int) (
84 (
unsigned int) upper % tab_size
85 + (
unsigned int) lower % tab_size
94 #define DFUNCTION "_sion_keyvalue_table_init" 100 DPRINTFP((2, DFUNCTION, -1,
"enter init size=%d\n",size));
109 if (entries == NULL) {
110 _sion_errorprint(0,_SION_ERROR_RETURN,
"cannot allocate internal keyvalue table entries of size %lu , aborting ...\n", (
unsigned long) size);
114 table->entries=entries;
118 table->num_added_entries=0;
119 table->iterator_lastreadindex=-1;
120 table->iterator_lastreadentry=NULL;
121 table->iterator_next=NULL;
122 table->iterator_head=NULL;
123 table->iterator_tail=NULL;
124 for(i=0;i<table->size;i++) {
125 table->entries[i].state=KEYVALUE_TABLE_ENTRY_STATE_FREE;
126 table->entries[i].key=0;
127 table->entries[i].iterator_next=NULL;
128 table->entries[i].next=NULL;
129 table->entries[i].data=NULL;
133 DPRINTFP((2, DFUNCTION, -1,
"leave\n"));
138 #define DFUNCTION "_sion_keyvalue_table_destroy" 140 size_t rc=SION_SUCCESS;
144 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
148 for(i=0;i<table->size;i++) {
150 if((table->entries[i].state!=KEYVALUE_TABLE_ENTRY_STATE_FREE) && (table->entries[i].data!=NULL)) {
151 _SION_SAFE_FREE(table->entries[i].data, NULL);
154 entry=table->entries[i].next;
155 while (entry != NULL) {
156 if((entry->state!=KEYVALUE_TABLE_ENTRY_STATE_FREE) && (entry->data!=NULL)) {
157 _SION_SAFE_FREE(entry->data, NULL);
159 next_entry=entry->next;
160 _SION_SAFE_FREE(entry, NULL);
165 free(table->entries);
172 DPRINTFP((2, DFUNCTION, -1,
"leave rc=%d\n",rc));
177 #define DFUNCTION "_sion_keyvalue_table_store" 179 size_t rc=SION_SUCCESS;
183 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
185 index = _sion_keyvalue_table_hash_fct(key,table->size);
186 DPRINTFP((2, DFUNCTION, -1,
"store entry with key %ld index=%d\n", (
long) key, index));
188 new_entry = &table->entries[index];
189 if (new_entry->state != KEYVALUE_TABLE_ENTRY_STATE_FREE) {
190 while (new_entry->next != NULL) {
191 new_entry = new_entry->next;
194 if (new_entry->next == NULL) {
195 return(
_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,
"cannot allocate internal keyvalue table entry, aborting ...\n"));
197 DPRINTFP((2, DFUNCTION, -1,
"add new entry to next list\n"));
198 table->num_added_entries++;
199 new_entry = new_entry->next;
203 new_entry->state= KEYVALUE_TABLE_ENTRY_STATE_USED;
204 new_entry->key = key;
205 new_entry->data = data;
206 new_entry->next = NULL;
207 new_entry->iterator_next = NULL;
209 if ( (table->iterator_head==NULL) && (table->iterator_tail==NULL) ) {
211 table->iterator_next=table->iterator_head=table->iterator_tail=new_entry;
213 table->iterator_tail->iterator_next=new_entry;
214 table->iterator_tail=table->iterator_tail->iterator_next;
218 DPRINTFP((2, DFUNCTION, -1,
"new entry successfully added (key %ld index=%d)\n", (
long) key, index));
219 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));
221 DPRINTFP((2, DFUNCTION, -1,
"leave rc=%d\n",rc));
226 #define DFUNCTION "_sion_keyvalue_table_lookup" 231 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
233 index = _sion_keyvalue_table_hash_fct(key,table->size);
234 DPRINTFP((2, DFUNCTION, -1,
"lookup entry with key %ld index=%d\n", (
long) key, index));
236 entry = &(table->entries[index]);
237 while (entry != NULL) {
239 DPRINTFP((2, DFUNCTION, -1,
"search: state=%ld\n",(
long) entry->state ));
241 if (entry->state == KEYVALUE_TABLE_ENTRY_STATE_USED) {
242 if(entry->key == key) {
243 DPRINTFP((2, DFUNCTION, -1,
"key found %ld in key list\n",(
long) entry->key ));
246 DPRINTFP((2, DFUNCTION, -1,
"skip this key another key found %ld in list\n",(
long) entry->key ));
254 DPRINTFP((2, DFUNCTION, -1,
"leave:entry not found\n"));
260 #define DFUNCTION "_sion_keyvalue_table_iterator_reset" 265 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
266 table->iterator_lastreadindex=-1;
267 table->iterator_lastreadentry=NULL;
268 table->iterator_next=table->iterator_head;
269 DPRINTFP((2, DFUNCTION, -1,
"leave\n"));
275 #define DFUNCTION "_sion_keyvalue_table_iterator_next_in_store_order" 276 int _sion_keyvalue_table_iterator_next_in_store_order(
_sion_keyvalue_table* table, sion_table_key_t *key,
void **data) {
279 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
281 return(SION_NOT_SUCCESS);
283 entry=table->iterator_next;
288 DPRINTFP((2, DFUNCTION, -1,
"found entry with key %ld\n",(
long) *key));
289 table->iterator_next=entry->iterator_next;
290 return(SION_SUCCESS);
292 return(SION_NOT_SUCCESS);
297 #define DFUNCTION "_sion_keyvalue_table_iterator_next" 298 int _sion_keyvalue_table_iterator_next(
_sion_keyvalue_table* table, sion_table_key_t *key,
void **data) {
300 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
302 return(SION_NOT_SUCCESS);
304 if(table->iterator_lastreadindex==-1) {
306 DPRINTFP((2, DFUNCTION, -1,
"start first\n"));
307 table->iterator_lastreadindex++;
308 while(table->iterator_lastreadindex < table->size) {
309 if (table->entries[table->iterator_lastreadindex].state == KEYVALUE_TABLE_ENTRY_STATE_USED) {
310 table->iterator_lastreadentry = &table->entries[table->iterator_lastreadindex];
313 table->iterator_lastreadindex++;
315 DPRINTFP((2, DFUNCTION, -1,
"start first, found entry at index %d\n",table->iterator_lastreadindex));
320 if(table->iterator_lastreadentry->next != NULL) {
321 table->iterator_lastreadentry=table->iterator_lastreadentry->next;
322 DPRINTFP((2, DFUNCTION, -1,
"found another entry in list at index %d\n",table->iterator_lastreadindex));
325 table->iterator_lastreadindex++;
326 while(table->iterator_lastreadindex < table->size) {
327 if (table->entries[table->iterator_lastreadindex].state == KEYVALUE_TABLE_ENTRY_STATE_USED) {
328 table->iterator_lastreadentry = &table->entries[table->iterator_lastreadindex];
329 DPRINTFP((2, DFUNCTION, -1,
"found entry at another index %d\n",table->iterator_lastreadindex));
332 table->iterator_lastreadindex++;
336 if(table->iterator_lastreadindex < table->size) {
337 *key=table->iterator_lastreadentry->key;
338 *data=table->iterator_lastreadentry->data;
339 DPRINTFP((2, DFUNCTION, -1,
"leave: entry found\n"));
340 return(SION_SUCCESS);
342 DPRINTFP((2, DFUNCTION, -1,
"leave: next entry not found\n"));
343 return(SION_NOT_SUCCESS);
348 #define DFUNCTION "_sion_keyvalue_table_get_size" 350 size_t help_bytes, bytes=0;
354 DPRINTFP((2, DFUNCTION, -1,
"enter\n"));
357 DPRINTFP((2, DFUNCTION, -1,
" sizeof key_table= %5d\n", help_bytes));
363 DPRINTFP((2, DFUNCTION, -1,
" sizeof key_entries= %5d\n", help_bytes));
367 for(i=0;i<table->size;i++) {
368 entry=table->entries[i].next;
369 while (entry != NULL) {
375 DPRINTFP((2, DFUNCTION, -1,
" sizeof key_addentries= %5d\n", help_bytes));
380 DPRINTFP((2, DFUNCTION, -1,
"leave bytes=%d\n",bytes));
int _sion_errorprint(int rc, int level, const char *format,...)
Internal SION error.