00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "xsb_config.h"
00027 #include "xsb_debug.h"
00028
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032
00033 #include "auxlry.h"
00034 #include "cell_xsb.h"
00035 #include "psc_xsb.h"
00036 #include "cinterf.h"
00037 #include "trie_internals.h"
00038 #include "macro_xsb.h"
00039 #include "error_xsb.h"
00040
00041 #include "tr_utils.h"
00042 #include "debug_xsb.h"
00043 #include "flags_xsb.h"
00044 #include "memory_xsb.h"
00045 #include "heap_xsb.h"
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #define table_hash(val, length) ((word)(val) % (length))
00057
00058 #define get_top_bucket(htable,I) \
00059 ((xsbBucket *)(htable->table + (htable->bucket_size * I)))
00060
00061
00062 #define mark_bucket_free(bucket,size) memset(bucket,(Cell)0,size)
00063 #define is_free_bucket(bucket) (bucket->name == (Cell)0)
00064
00065 static void init_hashtable(xsbHashTable *table);
00066
00067
00068 xsbBucket *search_bucket(Cell name,
00069 xsbHashTable *table,
00070 enum xsbHashSearchOp search_op)
00071 {
00072 xsbBucket *bucket, *prev;
00073
00074 if (! table->initted) init_hashtable(table);
00075
00076 prev = NULL;
00077 bucket = get_top_bucket(table,table_hash(name,table->length));
00078 while (bucket && bucket->name) {
00079 if (bucket->name == name) {
00080 if (search_op == hashtable_delete) {
00081 if (!prev) {
00082
00083
00084 prev = bucket;
00085 bucket=bucket->next;
00086 if (bucket) {
00087
00088 memcpy(prev, bucket, table->bucket_size);
00089 mem_dealloc(bucket,table->bucket_size,HASH_SPACE);
00090
00091 } else {
00092 mark_bucket_free(prev,table->bucket_size);
00093 xsb_dbgmsg((LOG_HASHTABLE,
00094 "SEARCH_BUCKET: Destroying storage handle for %s\n",
00095 string_val(name)));
00096 xsb_dbgmsg((LOG_HASHTABLE,
00097 "SEARCH_BUCKET: Bucket nameptr is %p, next bucket %p\n",
00098 prev->name, prev->next));
00099 }
00100 } else {
00101
00102 prev->next = bucket->next;
00103 mem_dealloc(bucket,table->bucket_size,HASH_SPACE);
00104
00105 }
00106 return NULL;
00107 } else
00108 return bucket;
00109 }
00110 prev = bucket;
00111 bucket = bucket->next;
00112 }
00113
00114 if (search_op != hashtable_insert) return NULL;
00115
00116
00117 if (!bucket) {
00118 bucket = (xsbBucket *)mem_calloc(1,table->bucket_size,HASH_SPACE);
00119
00120 if (!bucket)
00121 xsb_exit("Out of Memory: Can't allocate hash bucket");
00122 prev->next = bucket;
00123
00124 }
00125 bucket->name = name;
00126 return bucket;
00127 }
00128
00129
00130 static void init_hashtable(xsbHashTable *table)
00131 {
00132
00133 table->table = (byte *)mem_calloc(table->length,table->bucket_size,HASH_SPACE);
00134
00135 if (!table->table)
00136 xsb_exit("Out of Memory: Can't create hash table");
00137 table->initted = TRUE;
00138 }
00139
00140 void destroy_hashtable(xsbHashTable *table)
00141 {
00142 int i;
00143 xsbBucket *bucket, *next;
00144
00145 table->initted = FALSE;
00146 for (i=0; i < table->length; i++) {
00147
00148 bucket=get_top_bucket(table,i)->next;
00149 while (bucket != NULL) {
00150 next = bucket->next;
00151 mem_dealloc(bucket,table->bucket_size,HASH_SPACE);
00152
00153 bucket = next;
00154 }
00155 }
00156 mem_dealloc(table->table,table->length*table->bucket_size,HASH_SPACE);
00157
00158
00159 }
00160
00161
00162
00163 void show_table_state(xsbHashTable *table)
00164 {
00165 xsbBucket *bucket;
00166 int i;
00167
00168 xsb_dbgmsg((LOG_DEBUG,"\nCell Status\tOverflow Count\n"));
00169 for (i=0; i < table->length; i++) {
00170 bucket = get_top_bucket(table,i);
00171 if (is_free_bucket(bucket)) {
00172
00173 xsb_dbgmsg((LOG_DEBUG, " ---\t\t ---"));
00174 } else {
00175 int overflow_count=0;
00176
00177 fprintf(stddbg, " taken\t\t");
00178 bucket = bucket->next;
00179 while (bucket != NULL) {
00180 overflow_count++;
00181 bucket = bucket->next;
00182 }
00183 xsb_dbgmsg((LOG_DEBUG," %d", overflow_count));
00184 }
00185 }
00186 }
00187
00188 #ifndef MULTI_THREAD
00189
00190 extern xsbHashTable bt_storage_hash_table;
00191 #endif
00192
00193 void mark_hash_table_strings(CTXTdecl) {
00194 xsbBucket *bucket;
00195 int i;
00196 xsbHashTable *table;
00197
00198 table = &bt_storage_hash_table;
00199 if (table->initted==TRUE) {
00200 for (i=0; i < table->length; i++) {
00201 bucket = get_top_bucket(table,i);
00202 if (!is_free_bucket(bucket)) {
00203 if (bucket->name && isstring(bucket->name)) {
00204 mark_string(string_val(bucket->name),"hashtable");
00205 }
00206 bucket = bucket->next;
00207 while (bucket != NULL) {
00208 if (bucket->name && isstring(bucket->name)) {
00209 mark_string(string_val(bucket->name),"hashtable-b");
00210 }
00211 bucket = bucket->next;
00212 }
00213 }
00214 }
00215 }
00216 }