Home | History | Annotate | Download | only in libdb
      1 /**
      2  * @file db_debug.c
      3  * Debug routines for libdb
      4  *
      5  * @remark Copyright 2002 OProfile authors
      6  * @remark Read the file COPYING
      7  *
      8  * @author Philippe Elie
      9  */
     10 
     11 #include <stdio.h>
     12 #include <stdlib.h>
     13 #include <string.h>
     14 
     15 #include "odb.h"
     16 
     17 static int check_circular_list(odb_data_t const * data)
     18 {
     19 	odb_node_nr_t pos;
     20 	int do_abort = 0;
     21 	unsigned char * bitmap = malloc(data->descr->current_size);
     22 	memset(bitmap, '\0', data->descr->current_size);
     23 
     24 	for (pos = 0 ; pos < data->descr->size * BUCKET_FACTOR ; ++pos) {
     25 
     26 		odb_index_t index = data->hash_base[pos];
     27 		if (index && !do_abort) {
     28 			while (index) {
     29 				if (bitmap[index])
     30 					do_abort = 1;
     31 
     32 				bitmap[index] = 1;
     33 				index = data->node_base[index].next;
     34 			}
     35 		}
     36 
     37 		if (do_abort) {
     38 			printf("circular list detected size: %d\n",
     39 			       data->descr->current_size);
     40 
     41 			memset(bitmap, '\0', data->descr->current_size);
     42 
     43 			index = data->hash_base[pos];
     44 			while (index) {
     45 				printf("%d ", index);
     46 				if (bitmap[index])
     47 					exit(1);
     48 
     49 				bitmap[index] = 1;
     50 				index = data->node_base[index].next;
     51 			}
     52 		}
     53 
     54 		/* purely an optimization: intead of memset the map reset only
     55 		 * the needed part: not my use to optimize test but here the
     56 		 * test was so slow it was useless */
     57 		index = data->hash_base[pos];
     58 		while (index) {
     59 			bitmap[index] = 1;
     60 			index = data->node_base[index].next;
     61 		}
     62 	}
     63 
     64 	free(bitmap);
     65 
     66 	return do_abort;
     67 }
     68 
     69 static int check_redundant_key(odb_data_t const * data, odb_key_t max)
     70 {
     71 	odb_node_nr_t pos;
     72 
     73 	unsigned char * bitmap = malloc(max + 1);
     74 	memset(bitmap, '\0', max + 1);
     75 
     76 	for (pos = 1 ; pos < data->descr->current_size ; ++pos) {
     77 		if (bitmap[data->node_base[pos].key]) {
     78 			printf("redundant key found %lld\n",
     79 			       (unsigned long long)data->node_base[pos].key);
     80 			return 1;
     81 		}
     82 		bitmap[data->node_base[pos].key] = 1;
     83 	}
     84 	free(bitmap);
     85 
     86 	return 0;
     87 }
     88 
     89 int odb_check_hash(odb_t const * odb)
     90 {
     91 	odb_node_nr_t pos;
     92 	odb_node_nr_t nr_node = 0;
     93 	odb_node_nr_t nr_node_out_of_bound = 0;
     94 	int ret = 0;
     95 	odb_key_t max = 0;
     96 	odb_data_t * data = odb->data;
     97 
     98 	for (pos = 0 ; pos < data->descr->size * BUCKET_FACTOR ; ++pos) {
     99 		odb_index_t index = data->hash_base[pos];
    100 		while (index) {
    101 			if (index >= data->descr->current_size) {
    102 				nr_node_out_of_bound++;
    103 				break;
    104 			}
    105 			++nr_node;
    106 
    107 			if (data->node_base[index].key > max)
    108 				max = data->node_base[index].key;
    109 
    110 			index = data->node_base[index].next;
    111 		}
    112 	}
    113 
    114 	if (nr_node != data->descr->current_size - 1) {
    115 		printf("hash table walk found %d node expect %d node\n",
    116 		       nr_node, data->descr->current_size - 1);
    117 		ret = 1;
    118 	}
    119 
    120 	if (nr_node_out_of_bound) {
    121 		printf("out of bound node index: %d\n", nr_node_out_of_bound);
    122 		ret = 1;
    123 	}
    124 
    125 	if (ret == 0)
    126 		ret = check_circular_list(data);
    127 
    128 	if (ret == 0)
    129 		ret = check_redundant_key(data, max);
    130 
    131 	return ret;
    132 }
    133