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));