db_debug.c

Go to the documentation of this file.
00001 
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <string.h>
00014 
00015 #include "odb.h"
00016 
00017 static int check_circular_list(odb_data_t const * data)
00018 {
00019     odb_node_nr_t pos;
00020     int do_abort = 0;
00021     unsigned char * bitmap = malloc(data->descr->current_size);
00022     memset(bitmap, '\0', data->descr->current_size);
00023 
00024     for (pos = 0 ; pos < data->descr->size * BUCKET_FACTOR ; ++pos) {
00025 
00026         odb_index_t index = data->hash_base[pos];
00027         if (index && !do_abort) {
00028             while (index) {
00029                 if (bitmap[index])
00030                     do_abort = 1;
00031 
00032                 bitmap[index] = 1;
00033                 index = data->node_base[index].next;
00034             }
00035         }
00036 
00037         if (do_abort) {
00038             printf("circular list detected size: %d\n",
00039                    data->descr->current_size);
00040 
00041             memset(bitmap, '\0', data->descr->current_size);
00042 
00043             index = data->hash_base[pos];
00044             while (index) {
00045                 printf("%d ", index);
00046                 if (bitmap[index])
00047                     exit(1);
00048 
00049                 bitmap[index] = 1;
00050                 index = data->node_base[index].next;
00051             }
00052         }
00053 
00054         /* purely an optimization: intead of memset the map reset only
00055          * the needed part: not my use to optimize test but here the
00056          * test was so slow it was useless */
00057         index = data->hash_base[pos];
00058         while (index) {
00059             bitmap[index] = 1;
00060             index = data->node_base[index].next;
00061         }
00062     }
00063 
00064     free(bitmap);
00065 
00066     return do_abort;
00067 }
00068 
00069 static int check_redundant_key(odb_data_t const * data, odb_key_t max)
00070 {
00071     odb_node_nr_t pos;
00072 
00073     unsigned char * bitmap = malloc(max + 1);
00074     memset(bitmap, '\0', max + 1);
00075 
00076     for (pos = 1 ; pos < data->descr->current_size ; ++pos) {
00077         if (bitmap[data->node_base[pos].key]) {
00078             printf("redundant key found %lld\n",
00079                    (unsigned long long)data->node_base[pos].key);
00080             free(bitmap);
00081             return 1;
00082         }
00083         bitmap[data->node_base[pos].key] = 1;
00084     }
00085     free(bitmap);
00086 
00087     return 0;
00088 }
00089 
00090 int odb_check_hash(odb_t const * odb)
00091 {
00092     odb_node_nr_t pos;
00093     odb_node_nr_t nr_node = 0;
00094     odb_node_nr_t nr_node_out_of_bound = 0;
00095     int ret = 0;
00096     odb_key_t max = 0;
00097     odb_data_t * data = odb->data;
00098 
00099     for (pos = 0 ; pos < data->descr->size * BUCKET_FACTOR ; ++pos) {
00100         odb_index_t index = data->hash_base[pos];
00101         while (index) {
00102             if (index >= data->descr->current_size) {
00103                 nr_node_out_of_bound++;
00104                 break;
00105             }
00106             ++nr_node;
00107 
00108             if (data->node_base[index].key > max)
00109                 max = data->node_base[index].key;
00110 
00111             index = data->node_base[index].next;
00112         }
00113     }
00114 
00115     if (nr_node != data->descr->current_size - 1) {
00116         printf("hash table walk found %d node expect %d node\n",
00117                nr_node, data->descr->current_size - 1);
00118         ret = 1;
00119     }
00120 
00121     if (nr_node_out_of_bound) {
00122         printf("out of bound node index: %d\n", nr_node_out_of_bound);
00123         ret = 1;
00124     }
00125 
00126     if (ret == 0)
00127         ret = check_circular_list(data);
00128 
00129     if (ret == 0)
00130         ret = check_redundant_key(data, max);
00131 
00132     return ret;
00133 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1