Created
November 17, 2011 13:44
-
-
Save larskanis/1373160 to your computer and use it in GitHub Desktop.
Differences between st.h in rbx and st.c in mri-1.9.3 regarding to https://github.com/rubinius/rubinius/pull/1383
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- /home/lars/.rvm/src/ruby-1.9.3-p0/st.c 2011-01-27 15:30:00.000000000 +0100 | |
+++ vm/capi/19/include/ruby/st.h 2011-10-28 23:17:41.741629969 +0200 | |
@@ -1,18 +1,89 @@ | |
/* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */ | |
-/* static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible"; */ | |
+/* @(#) st.h 5.1 89/12/14 */ | |
+ | |
+#ifndef RUBY_ST_H | |
+#define RUBY_ST_H 1 | |
+ | |
+#if defined(__cplusplus) | |
+extern "C" { | |
+#if 0 | |
+} /* satisfy cc-mode */ | |
+#endif | |
+#endif | |
+ | |
+#if defined __GNUC__ && __GNUC__ >= 4 | |
+#pragma GCC visibility push(default) | |
+#endif | |
-#ifdef NOT_RUBY | |
-#include "regint.h" | |
-#include "st.h" | |
+#if SIZEOF_LONG == SIZEOF_VOIDP | |
+typedef unsigned long st_data_t; | |
+#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP | |
+typedef unsigned LONG_LONG st_data_t; | |
#else | |
-#include "ruby/ruby.h" | |
+# error ---->> st.c requires sizeof(void*) == sizeof(long) to be compiled. <<---- | |
+#endif | |
+#define ST_DATA_T_DEFINED | |
+ | |
+#ifndef CHAR_BIT | |
+# ifdef HAVE_LIMITS_H | |
+# include <limits.h> | |
+# else | |
+# define CHAR_BIT 8 | |
+# endif | |
+#endif | |
+ | |
+typedef struct st_table st_table; | |
+ | |
+typedef st_data_t st_index_t; | |
+typedef int st_compare_func(st_data_t, st_data_t); | |
+typedef st_index_t st_hash_func(st_data_t); | |
+ | |
+typedef char st_check_for_sizeof_st_index_t[SIZEOF_VOIDP == (int)sizeof(st_index_t) ? 1 : -1]; | |
+#define SIZEOF_ST_INDEX_T SIZEOF_VOIDP | |
+ | |
+struct st_hash_type { | |
+ int (*compare)(ANYARGS /*st_data_t, st_data_t*/); /* st_compare_func* */ | |
+ st_index_t (*hash)(ANYARGS /*st_data_t*/); /* st_hash_func* */ | |
+}; | |
+ | |
+#define ST_INDEX_BITS (sizeof(st_index_t) * CHAR_BIT) | |
+ | |
+struct st_table { | |
+ const struct st_hash_type *type; | |
+ st_index_t num_bins; | |
+ unsigned int entries_packed : 1; | |
+#ifdef __GNUC__ | |
+ /* | |
+ * C spec says, | |
+ * A bit-field shall have a type that is a qualified or unqualified | |
+ * version of _Bool, signed int, unsigned int, or some other | |
+ * implementation-defined type. It is implementation-defined whether | |
+ * atomic types are permitted. | |
+ * In short, long and long long bit-field are implementation-defined | |
+ * feature. Therefore we want to supress a warning explicitly. | |
+ */ | |
+ __extension__ | |
#endif | |
+ st_index_t num_entries : ST_INDEX_BITS - 1; | |
+ struct st_table_entry **bins; | |
+ struct st_table_entry *head, *tail; | |
+}; | |
+ | |
+#define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0) | |
+ | |
+enum st_retval {ST_CONTINUE = 0, ST_STOP = 1, ST_DELETE = 2, ST_CHECK}; | |
+ | |
+ | |
+/* This is st.c, stuck in here, and with all the functions set to static. */ | |
+ | |
+ | |
+/* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */ | |
+ | |
+/* static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible"; */ | |
#include <stdio.h> | |
-#ifdef HAVE_STDLIB_H | |
#include <stdlib.h> | |
-#endif | |
#include <string.h> | |
typedef struct st_table_entry st_table_entry; | |
@@ -38,53 +109,51 @@ | |
* | |
*/ | |
+static int st_numcmp(st_data_t, st_data_t); | |
+static st_index_t st_numhash(st_data_t); | |
static const struct st_hash_type type_numhash = { | |
- st_numcmp, | |
- st_numhash, | |
+ (int (*)(ANYARGS))st_numcmp, | |
+ (st_index_t (*)(ANYARGS))st_numhash, | |
}; | |
/* extern int strcmp(const char *, const char *); */ | |
-static st_index_t strhash(st_data_t); | |
-static const struct st_hash_type type_strhash = { | |
- strcmp, | |
- strhash, | |
+static st_index_t st_internal_strhash(st_data_t); | |
+static const struct st_hash_type type_st_internal_strhash = { | |
+ (int (*)(ANYARGS))strcmp, | |
+ (st_index_t (*)(ANYARGS))st_internal_strhash, | |
}; | |
-static st_index_t strcasehash(st_data_t); | |
-static const struct st_hash_type type_strcasehash = { | |
- st_strcasecmp, | |
- strcasehash, | |
+static int st_strcasecmp(const char *, const char *); | |
+static st_index_t st_internal_strcasehash(st_data_t); | |
+static const struct st_hash_type type_st_internal_strcasehash = { | |
+ (int (*)(ANYARGS))st_strcasecmp, | |
+ (st_index_t (*)(ANYARGS))st_internal_strcasehash, | |
}; | |
-static void rehash(st_table *); | |
- | |
-#ifdef RUBY | |
-#define malloc xmalloc | |
-#define calloc xcalloc | |
-#define free(x) xfree(x) | |
-#endif | |
+static void st_internal_rehash(st_table *); | |
+static int st_insert(register st_table *, register st_data_t, st_data_t); | |
-#define numberof(array) (int)(sizeof(array) / sizeof((array)[0])) | |
+#define st_internal_numberof(array) (int)(sizeof(array) / sizeof((array)[0])) | |
-#define alloc(type) (type*)malloc((size_t)sizeof(type)) | |
-#define Calloc(n,s) (char*)calloc((n),(s)) | |
+#define st_internal_alloc(type) (type*)xmalloc((size_t)sizeof(type)) | |
+#define st_internal_calloc(n,s) (char*)xcalloc((n),(s)) | |
-#define EQUAL(table,x,y) ((x)==(y) || (*(table)->type->compare)((x),(y)) == 0) | |
+#define ST_EQUAL(table,x,y) ((x)==(y) || (*(table)->type->compare)((x),(y)) == 0) | |
/* remove cast to unsigned int in the future */ | |
-#define do_hash(key,table) (unsigned int)(st_index_t)(*(table)->type->hash)((key)) | |
-#define do_hash_bin(key,table) (do_hash((key), (table))%(table)->num_bins) | |
+#define st_do_hash(key,table) (unsigned int)(st_index_t)(*(table)->type->hash)((key)) | |
+#define st_do_hash_bin(key,table) (st_do_hash((key), (table))%(table)->num_bins) | |
/* | |
- * MINSIZE is the minimum size of a dictionary. | |
+ * ST_MINSIZE is the minimum size of a dictionary. | |
*/ | |
-#define MINSIZE 8 | |
+#define ST_MINSIZE 8 | |
/* | |
Table of prime numbers 2^n+a, 2<=n<=30. | |
*/ | |
-static const unsigned int primes[] = { | |
+static const unsigned int st_internal_primes[] = { | |
8 + 3, | |
16 + 3, | |
32 + 5, | |
@@ -117,127 +186,84 @@ | |
}; | |
static st_index_t | |
-new_size(st_index_t size) | |
+st_internal_new_size(st_index_t size) | |
{ | |
int i; | |
-#if 0 | |
- for (i=3; i<31; i++) { | |
- if ((1<<i) > size) return 1<<i; | |
- } | |
- return -1; | |
-#else | |
st_index_t newsize; | |
- for (i = 0, newsize = MINSIZE; i < numberof(primes); i++, newsize <<= 1) { | |
- if (newsize > size) return primes[i]; | |
+ for (i = 0, newsize = ST_MINSIZE; i < st_internal_numberof(st_internal_primes); i++, newsize <<= 1) { | |
+ if (newsize > size) return st_internal_primes[i]; | |
} | |
/* Ran out of polynomials */ | |
-#ifndef NOT_RUBY | |
rb_raise(rb_eRuntimeError, "st_table too big"); | |
-#endif | |
return -1; /* should raise exception */ | |
-#endif | |
-} | |
- | |
-#ifdef HASH_LOG | |
-#ifdef HAVE_UNISTD_H | |
-#include <unistd.h> | |
-#endif | |
-static struct { | |
- int all, total, num, str, strcase; | |
-} collision; | |
-static int init_st = 0; | |
- | |
-static void | |
-stat_col(void) | |
-{ | |
- char fname[10+sizeof(long)*3]; | |
- FILE *f = fopen((snprintf(fname, sizeof(fname), "/tmp/col%ld", (long)getpid()), fname), "w"); | |
- fprintf(f, "collision: %d / %d (%6.2f)\n", collision.all, collision.total, | |
- ((double)collision.all / (collision.total)) * 100); | |
- fprintf(f, "num: %d, str: %d, strcase: %d\n", collision.num, collision.str, collision.strcase); | |
- fclose(f); | |
} | |
-#endif | |
-#define MAX_PACKED_NUMHASH (ST_DEFAULT_INIT_TABLE_SIZE/2) | |
+#define ST_MAX_PACKED_NUMHASH (ST_DEFAULT_INIT_TABLE_SIZE/2) | |
-st_table* | |
+static st_table* | |
st_init_table_with_size(const struct st_hash_type *type, st_index_t size) | |
{ | |
st_table *tbl; | |
-#ifdef HASH_LOG | |
-# if HASH_LOG+0 < 0 | |
- { | |
- const char *e = getenv("ST_HASH_LOG"); | |
- if (!e || !*e) init_st = 1; | |
- } | |
-# endif | |
- if (init_st == 0) { | |
- init_st = 1; | |
- atexit(stat_col); | |
- } | |
-#endif | |
+ size = st_internal_new_size(size); /* round up to prime number */ | |
- size = new_size(size); /* round up to prime number */ | |
- | |
- tbl = alloc(st_table); | |
+ tbl = st_internal_alloc(st_table); | |
tbl->type = type; | |
tbl->num_entries = 0; | |
- tbl->entries_packed = type == &type_numhash && size/2 <= MAX_PACKED_NUMHASH; | |
+ tbl->entries_packed = type == &type_numhash && size/2 <= ST_MAX_PACKED_NUMHASH; | |
tbl->num_bins = size; | |
- tbl->bins = (st_table_entry **)Calloc(size, sizeof(st_table_entry*)); | |
+ tbl->bins = (st_table_entry **)st_internal_calloc(size, sizeof(st_table_entry*)); | |
tbl->head = 0; | |
tbl->tail = 0; | |
return tbl; | |
} | |
-st_table* | |
+static st_table* | |
st_init_table(const struct st_hash_type *type) | |
{ | |
return st_init_table_with_size(type, 0); | |
} | |
-st_table* | |
+static st_table* | |
st_init_numtable(void) | |
{ | |
return st_init_table(&type_numhash); | |
} | |
-st_table* | |
+static st_table* | |
st_init_numtable_with_size(st_index_t size) | |
{ | |
return st_init_table_with_size(&type_numhash, size); | |
} | |
-st_table* | |
+static st_table* | |
st_init_strtable(void) | |
{ | |
- return st_init_table(&type_strhash); | |
+ return st_init_table(&type_st_internal_strhash); | |
} | |
-st_table* | |
+static st_table* | |
st_init_strtable_with_size(st_index_t size) | |
{ | |
- return st_init_table_with_size(&type_strhash, size); | |
+ return st_init_table_with_size(&type_st_internal_strhash, size); | |
} | |
-st_table* | |
+static st_table* | |
st_init_strcasetable(void) | |
{ | |
- return st_init_table(&type_strcasehash); | |
+ return st_init_table(&type_st_internal_strcasehash); | |
} | |
-st_table* | |
+static st_table* | |
st_init_strcasetable_with_size(st_index_t size) | |
{ | |
- return st_init_table_with_size(&type_strcasehash, size); | |
+ return st_init_table_with_size(&type_st_internal_strcasehash, size); | |
} | |
-void | |
+static void | |
st_clear(st_table *table) | |
{ | |
register st_table_entry *ptr, *next; | |
@@ -262,7 +288,7 @@ | |
table->tail = 0; | |
} | |
-void | |
+static void | |
st_free_table(st_table *table) | |
{ | |
st_clear(table); | |
@@ -270,7 +296,7 @@ | |
free(table); | |
} | |
-size_t | |
+static size_t | |
st_memsize(const st_table *table) | |
{ | |
if (table->entries_packed) { | |
@@ -281,47 +307,21 @@ | |
} | |
} | |
-#define PTR_NOT_EQUAL(table, ptr, hash_val, key) \ | |
-((ptr) != 0 && ((ptr)->hash != (hash_val) || !EQUAL((table), (key), (ptr)->key))) | |
- | |
-#ifdef HASH_LOG | |
-static void | |
-count_collision(const struct st_hash_type *type) | |
-{ | |
- collision.all++; | |
- if (type == &type_numhash) { | |
- collision.num++; | |
- } | |
- else if (type == &type_strhash) { | |
- collision.strcase++; | |
- } | |
- else if (type == &type_strcasehash) { | |
- collision.str++; | |
- } | |
-} | |
-#define COLLISION (collision_check ? count_collision(table->type) : (void)0) | |
-#define FOUND_ENTRY (collision_check ? collision.total++ : (void)0) | |
-#else | |
-#define COLLISION | |
-#define FOUND_ENTRY | |
-#endif | |
+#define ST_PTR_NOT_EQUAL(table, ptr, hash_val, key) \ | |
+((ptr) != 0 && ((ptr)->hash != (hash_val) || !ST_EQUAL((table), (key), (ptr)->key))) | |
-#define FIND_ENTRY(table, ptr, hash_val, bin_pos) do {\ | |
+#define ST_FIND_ENTRY(table, ptr, hash_val, bin_pos) do {\ | |
(bin_pos) = (hash_val)%(table)->num_bins;\ | |
(ptr) = (table)->bins[(bin_pos)];\ | |
- FOUND_ENTRY;\ | |
- if (PTR_NOT_EQUAL((table), (ptr), (hash_val), key)) {\ | |
- COLLISION;\ | |
- while (PTR_NOT_EQUAL((table), (ptr)->next, (hash_val), key)) {\ | |
+ if (ST_PTR_NOT_EQUAL((table), (ptr), (hash_val), key)) {\ | |
+ while (ST_PTR_NOT_EQUAL((table), (ptr)->next, (hash_val), key)) {\ | |
(ptr) = (ptr)->next;\ | |
}\ | |
(ptr) = (ptr)->next;\ | |
}\ | |
} while (0) | |
-#define collision_check 0 | |
- | |
-int | |
+static int | |
st_lookup(st_table *table, register st_data_t key, st_data_t *value) | |
{ | |
st_index_t hash_val, bin_pos; | |
@@ -338,8 +338,8 @@ | |
return 0; | |
} | |
- hash_val = do_hash(key, table); | |
- FIND_ENTRY(table, ptr, hash_val, bin_pos); | |
+ hash_val = st_do_hash(key, table); | |
+ ST_FIND_ENTRY(table, ptr, hash_val, bin_pos); | |
if (ptr == 0) { | |
return 0; | |
@@ -350,7 +350,7 @@ | |
} | |
} | |
-int | |
+static int | |
st_get_key(st_table *table, register st_data_t key, st_data_t *result) | |
{ | |
st_index_t hash_val, bin_pos; | |
@@ -367,8 +367,8 @@ | |
return 0; | |
} | |
- hash_val = do_hash(key, table); | |
- FIND_ENTRY(table, ptr, hash_val, bin_pos); | |
+ hash_val = st_do_hash(key, table); | |
+ ST_FIND_ENTRY(table, ptr, hash_val, bin_pos); | |
if (ptr == 0) { | |
return 0; | |
@@ -379,22 +379,19 @@ | |
} | |
} | |
-#undef collision_check | |
-#define collision_check 1 | |
- | |
-#define MORE_PACKABLE_P(table) \ | |
+#define ST_MORE_PACKABLE_P(table) \ | |
((st_index_t)((table)->num_entries+1) * 2 <= (table)->num_bins && \ | |
- (table)->num_entries+1 <= MAX_PACKED_NUMHASH) | |
+ (table)->num_entries+1 <= ST_MAX_PACKED_NUMHASH) | |
-#define ADD_DIRECT(table, key, value, hash_val, bin_pos)\ | |
+#define ST_ADD_DIRECT(table, key, value, hash_val, bin_pos)\ | |
do {\ | |
st_table_entry *entry;\ | |
if ((table)->num_entries > ST_DEFAULT_MAX_DENSITY * (table)->num_bins) {\ | |
- rehash(table);\ | |
+ st_internal_rehash(table);\ | |
(bin_pos) = (hash_val) % (table)->num_bins;\ | |
}\ | |
\ | |
- entry = alloc(st_table_entry);\ | |
+ entry = st_internal_alloc(st_table_entry);\ | |
\ | |
entry->hash = (hash_val);\ | |
entry->key = (key);\ | |
@@ -414,10 +411,10 @@ | |
} while (0) | |
static void | |
-unpack_entries(register st_table *table) | |
+st_internal_unpack_entries(register st_table *table) | |
{ | |
st_index_t i; | |
- struct st_table_entry *packed_bins[MAX_PACKED_NUMHASH*2]; | |
+ struct st_table_entry *packed_bins[ST_MAX_PACKED_NUMHASH*2]; | |
st_table tmp_table = *table; | |
memcpy(packed_bins, table->bins, sizeof(struct st_table_entry *) * table->num_entries*2); | |
@@ -431,7 +428,7 @@ | |
*table = tmp_table; | |
} | |
-int | |
+static int | |
st_insert(register st_table *table, register st_data_t key, st_data_t value) | |
{ | |
st_index_t hash_val, bin_pos; | |
@@ -445,22 +442,22 @@ | |
return 1; | |
} | |
} | |
- if (MORE_PACKABLE_P(table)) { | |
+ if (ST_MORE_PACKABLE_P(table)) { | |
i = table->num_entries++; | |
table->bins[i*2] = (struct st_table_entry*)key; | |
table->bins[i*2+1] = (struct st_table_entry*)value; | |
return 0; | |
} | |
else { | |
- unpack_entries(table); | |
+ st_internal_unpack_entries(table); | |
} | |
} | |
- hash_val = do_hash(key, table); | |
- FIND_ENTRY(table, ptr, hash_val, bin_pos); | |
+ hash_val = st_do_hash(key, table); | |
+ ST_FIND_ENTRY(table, ptr, hash_val, bin_pos); | |
if (ptr == 0) { | |
- ADD_DIRECT(table, key, value, hash_val, bin_pos); | |
+ ST_ADD_DIRECT(table, key, value, hash_val, bin_pos); | |
return 0; | |
} | |
else { | |
@@ -469,7 +466,7 @@ | |
} | |
} | |
-int | |
+static int | |
st_insert2(register st_table *table, register st_data_t key, st_data_t value, | |
st_data_t (*func)(st_data_t)) | |
{ | |
@@ -484,23 +481,23 @@ | |
return 1; | |
} | |
} | |
- if (MORE_PACKABLE_P(table)) { | |
+ if (ST_MORE_PACKABLE_P(table)) { | |
i = table->num_entries++; | |
table->bins[i*2] = (struct st_table_entry*)key; | |
table->bins[i*2+1] = (struct st_table_entry*)value; | |
return 0; | |
} | |
else { | |
- unpack_entries(table); | |
+ st_internal_unpack_entries(table); | |
} | |
} | |
- hash_val = do_hash(key, table); | |
- FIND_ENTRY(table, ptr, hash_val, bin_pos); | |
+ hash_val = st_do_hash(key, table); | |
+ ST_FIND_ENTRY(table, ptr, hash_val, bin_pos); | |
if (ptr == 0) { | |
key = (*func)(key); | |
- ADD_DIRECT(table, key, value, hash_val, bin_pos); | |
+ ST_ADD_DIRECT(table, key, value, hash_val, bin_pos); | |
return 0; | |
} | |
else { | |
@@ -509,36 +506,36 @@ | |
} | |
} | |
-void | |
+static void | |
st_add_direct(st_table *table, st_data_t key, st_data_t value) | |
{ | |
st_index_t hash_val, bin_pos; | |
if (table->entries_packed) { | |
int i; | |
- if (MORE_PACKABLE_P(table)) { | |
+ if (ST_MORE_PACKABLE_P(table)) { | |
i = table->num_entries++; | |
table->bins[i*2] = (struct st_table_entry*)key; | |
table->bins[i*2+1] = (struct st_table_entry*)value; | |
return; | |
} | |
else { | |
- unpack_entries(table); | |
+ st_internal_unpack_entries(table); | |
} | |
} | |
- hash_val = do_hash(key, table); | |
+ hash_val = st_do_hash(key, table); | |
bin_pos = hash_val % table->num_bins; | |
- ADD_DIRECT(table, key, value, hash_val, bin_pos); | |
+ ST_ADD_DIRECT(table, key, value, hash_val, bin_pos); | |
} | |
static void | |
-rehash(register st_table *table) | |
+st_internal_rehash(register st_table *table) | |
{ | |
register st_table_entry *ptr, **new_bins; | |
st_index_t i, new_num_bins, hash_val; | |
- new_num_bins = new_size(table->num_bins+1); | |
+ new_num_bins = st_internal_new_size(table->num_bins+1); | |
new_bins = (st_table_entry**) | |
xrealloc(table->bins, new_num_bins * sizeof(st_table_entry*)); | |
for (i = 0; i < new_num_bins; ++i) new_bins[i] = 0; | |
@@ -554,7 +551,7 @@ | |
} | |
} | |
-st_table* | |
+static st_table* | |
st_copy(st_table *old_table) | |
{ | |
st_table *new_table; | |
@@ -562,14 +559,14 @@ | |
st_index_t num_bins = old_table->num_bins; | |
st_index_t hash_val; | |
- new_table = alloc(st_table); | |
+ new_table = st_internal_alloc(st_table); | |
if (new_table == 0) { | |
return 0; | |
} | |
*new_table = *old_table; | |
new_table->bins = (st_table_entry**) | |
- Calloc((unsigned)num_bins, sizeof(st_table_entry*)); | |
+ st_internal_calloc((unsigned)num_bins, sizeof(st_table_entry*)); | |
if (new_table->bins == 0) { | |
free(new_table); | |
@@ -585,7 +582,7 @@ | |
prev = 0; | |
tail = &new_table->head; | |
do { | |
- entry = alloc(st_table_entry); | |
+ entry = st_internal_alloc(st_table_entry); | |
if (entry == 0) { | |
st_free_table(new_table); | |
return 0; | |
@@ -604,7 +601,7 @@ | |
return new_table; | |
} | |
-#define REMOVE_ENTRY(table, ptr) do \ | |
+#define ST_REMOVE_ENTRY(table, ptr) do \ | |
{ \ | |
if ((ptr)->fore == 0 && (ptr)->back == 0) { \ | |
(table)->head = 0; \ | |
@@ -620,7 +617,7 @@ | |
(table)->num_entries--; \ | |
} while (0) | |
-int | |
+static int | |
st_delete(register st_table *table, register st_data_t *key, st_data_t *value) | |
{ | |
st_index_t hash_val; | |
@@ -642,12 +639,12 @@ | |
return 0; | |
} | |
- hash_val = do_hash_bin(*key, table); | |
+ hash_val = st_do_hash_bin(*key, table); | |
for (prev = &table->bins[hash_val]; (ptr = *prev) != 0; prev = &ptr->next) { | |
- if (EQUAL(table, *key, ptr->key)) { | |
+ if (ST_EQUAL(table, *key, ptr->key)) { | |
*prev = ptr->next; | |
- REMOVE_ENTRY(table, ptr); | |
+ ST_REMOVE_ENTRY(table, ptr); | |
if (value != 0) *value = ptr->record; | |
*key = ptr->key; | |
free(ptr); | |
@@ -659,7 +656,7 @@ | |
return 0; | |
} | |
-int | |
+static int | |
st_delete_safe(register st_table *table, register st_data_t *key, st_data_t *value, st_data_t never) | |
{ | |
st_index_t hash_val; | |
@@ -670,7 +667,7 @@ | |
for (i = 0; i < table->num_entries; i++) { | |
if ((st_data_t)table->bins[i*2] == *key) { | |
if (value != 0) *value = (st_data_t)table->bins[i*2+1]; | |
- table->bins[i*2] = (void *)never; | |
+ table->bins[i*2] = (st_table_entry *)never; | |
return 1; | |
} | |
} | |
@@ -678,12 +675,12 @@ | |
return 0; | |
} | |
- hash_val = do_hash_bin(*key, table); | |
+ hash_val = st_do_hash_bin(*key, table); | |
ptr = table->bins[hash_val]; | |
for (; ptr != 0; ptr = ptr->next) { | |
- if ((ptr->key != never) && EQUAL(table, ptr->key, *key)) { | |
- REMOVE_ENTRY(table, ptr); | |
+ if ((ptr->key != never) && ST_EQUAL(table, ptr->key, *key)) { | |
+ ST_REMOVE_ENTRY(table, ptr); | |
*key = ptr->key; | |
if (value != 0) *value = ptr->record; | |
ptr->key = ptr->record = never; | |
@@ -695,7 +692,7 @@ | |
return 0; | |
} | |
-void | |
+static void | |
st_cleanup_safe(st_table *table, st_data_t never) | |
{ | |
st_table_entry *ptr, **last, *tmp; | |
@@ -731,7 +728,7 @@ | |
} | |
} | |
-int | |
+static int | |
st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) | |
{ | |
st_table_entry *ptr, **last, *tmp; | |
@@ -744,7 +741,7 @@ | |
st_data_t key, val; | |
key = (st_data_t)table->bins[i*2]; | |
val = (st_data_t)table->bins[i*2+1]; | |
- retval = (*func)(key, val, arg); | |
+ retval = (enum st_retval)func(key, val, arg); | |
if (!table->entries_packed) goto unpacked; | |
switch (retval) { | |
case ST_CHECK: /* check if hash is modified during iteration */ | |
@@ -754,7 +751,7 @@ | |
} | |
if (j == table->num_entries) { | |
/* call func with error notice */ | |
- retval = (*func)(0, 0, arg, 1); | |
+ retval = (enum st_retval)func(0, 0, arg, 1); | |
return 1; | |
} | |
/* fall through */ | |
@@ -784,13 +781,13 @@ | |
if (ptr != 0) { | |
do { | |
i = ptr->hash % table->num_bins; | |
- retval = (*func)(ptr->key, ptr->record, arg); | |
+ retval = (enum st_retval)func(ptr->key, ptr->record, arg); | |
switch (retval) { | |
case ST_CHECK: /* check if hash is modified during iteration */ | |
for (tmp = table->bins[i]; tmp != ptr; tmp = tmp->next) { | |
if (!tmp) { | |
/* call func with error notice */ | |
- retval = (*func)(0, 0, arg, 1); | |
+ retval = (enum st_retval)func(0, 0, arg, 1); | |
return 1; | |
} | |
} | |
@@ -806,7 +803,7 @@ | |
if (ptr == tmp) { | |
tmp = ptr->fore; | |
*last = ptr->next; | |
- REMOVE_ENTRY(table, ptr); | |
+ ST_REMOVE_ENTRY(table, ptr); | |
free(ptr); | |
if (ptr == tmp) return 0; | |
ptr = tmp; | |
@@ -819,88 +816,6 @@ | |
return 0; | |
} | |
-#if 0 /* unused right now */ | |
-int | |
-st_reverse_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) | |
-{ | |
- st_table_entry *ptr, **last, *tmp; | |
- enum st_retval retval; | |
- int i; | |
- | |
- if (table->entries_packed) { | |
- for (i = table->num_entries-1; 0 <= i; i--) { | |
- int j; | |
- st_data_t key, val; | |
- key = (st_data_t)table->bins[i*2]; | |
- val = (st_data_t)table->bins[i*2+1]; | |
- retval = (*func)(key, val, arg); | |
- switch (retval) { | |
- case ST_CHECK: /* check if hash is modified during iteration */ | |
- for (j = 0; j < table->num_entries; j++) { | |
- if ((st_data_t)table->bins[j*2] == key) | |
- break; | |
- } | |
- if (j == table->num_entries) { | |
- /* call func with error notice */ | |
- retval = (*func)(0, 0, arg, 1); | |
- return 1; | |
- } | |
- /* fall through */ | |
- case ST_CONTINUE: | |
- break; | |
- case ST_STOP: | |
- return 0; | |
- case ST_DELETE: | |
- table->num_entries--; | |
- memmove(&table->bins[i*2], &table->bins[(i+1)*2], | |
- sizeof(struct st_table_entry*) * 2*(table->num_entries-i)); | |
- break; | |
- } | |
- } | |
- return 0; | |
- } | |
- | |
- if ((ptr = table->head) != 0) { | |
- ptr = ptr->back; | |
- do { | |
- retval = (*func)(ptr->key, ptr->record, arg, 0); | |
- switch (retval) { | |
- case ST_CHECK: /* check if hash is modified during iteration */ | |
- i = ptr->hash % table->num_bins; | |
- for (tmp = table->bins[i]; tmp != ptr; tmp = tmp->next) { | |
- if (!tmp) { | |
- /* call func with error notice */ | |
- retval = (*func)(0, 0, arg, 1); | |
- return 1; | |
- } | |
- } | |
- /* fall through */ | |
- case ST_CONTINUE: | |
- ptr = ptr->back; | |
- break; | |
- case ST_STOP: | |
- return 0; | |
- case ST_DELETE: | |
- last = &table->bins[ptr->hash % table->num_bins]; | |
- for (; (tmp = *last) != 0; last = &tmp->next) { | |
- if (ptr == tmp) { | |
- tmp = ptr->back; | |
- *last = ptr->next; | |
- REMOVE_ENTRY(table, ptr); | |
- free(ptr); | |
- ptr = tmp; | |
- break; | |
- } | |
- } | |
- ptr = ptr->next; | |
- free(tmp); | |
- table->num_entries--; | |
- } | |
- } while (ptr && table->head); | |
- } | |
- return 0; | |
-} | |
-#endif | |
/* | |
* hash_32 - 32 bit Fowler/Noll/Vo FNV-1a hash code | |
@@ -936,7 +851,7 @@ | |
* for more details as well as other forms of the FNV hash. | |
*** | |
* | |
- * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the | |
+ * To use the recommended 32 bit FNV-1a hash, pass ST_FNV1_32A_INIT as the | |
* Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str(). | |
* | |
*** | |
@@ -970,19 +885,18 @@ | |
* | |
* NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition. | |
*/ | |
-#define FNV1_32A_INIT 0x811c9dc5 | |
+#define ST_FNV1_32A_INIT 0x811c9dc5 | |
/* | |
* 32 bit magic FNV-1a prime | |
*/ | |
-#define FNV_32_PRIME 0x01000193 | |
+#define ST_FNV_32_PRIME 0x01000193 | |
-#ifdef ST_USE_FNV1 | |
static st_index_t | |
-strhash(st_data_t arg) | |
+st_internal_strhash(st_data_t arg) | |
{ | |
register const char *string = (const char *)arg; | |
- register st_index_t hval = FNV1_32A_INIT; | |
+ register st_index_t hval = ST_FNV1_32A_INIT; | |
/* | |
* FNV-1a hash each octet in the buffer | |
@@ -992,267 +906,12 @@ | |
hval ^= (unsigned int)*string++; | |
/* multiply by the 32 bit FNV magic prime mod 2^32 */ | |
- hval *= FNV_32_PRIME; | |
+ hval *= ST_FNV_32_PRIME; | |
} | |
return hval; | |
} | |
-#else | |
- | |
-#ifndef UNALIGNED_WORD_ACCESS | |
-# if defined __i386__ || defined _M_IX86 | |
-# define UNALIGNED_WORD_ACCESS 1 | |
-# endif | |
-#endif | |
-#ifndef UNALIGNED_WORD_ACCESS | |
-# define UNALIGNED_WORD_ACCESS 0 | |
-#endif | |
- | |
-/* MurmurHash described in http://murmurhash.googlepages.com/ */ | |
-#ifndef MURMUR | |
-#define MURMUR 2 | |
-#endif | |
- | |
-#define MurmurMagic_1 (st_index_t)0xc6a4a793 | |
-#define MurmurMagic_2 (st_index_t)0x5bd1e995 | |
-#if MURMUR == 1 | |
-#define MurmurMagic MurmurMagic_1 | |
-#elif MURMUR == 2 | |
-#if SIZEOF_ST_INDEX_T > 4 | |
-#define MurmurMagic ((MurmurMagic_1 << 32) | MurmurMagic_2) | |
-#else | |
-#define MurmurMagic MurmurMagic_2 | |
-#endif | |
-#endif | |
- | |
-static inline st_index_t | |
-murmur(st_index_t h, st_index_t k, int r) | |
-{ | |
- const st_index_t m = MurmurMagic; | |
-#if MURMUR == 1 | |
- h += k; | |
- h *= m; | |
- h ^= h >> r; | |
-#elif MURMUR == 2 | |
- k *= m; | |
- k ^= k >> r; | |
- k *= m; | |
- | |
- h *= m; | |
- h ^= k; | |
-#endif | |
- return h; | |
-} | |
- | |
-static inline st_index_t | |
-murmur_finish(st_index_t h) | |
-{ | |
-#if MURMUR == 1 | |
- h = murmur(h, 0, 10); | |
- h = murmur(h, 0, 17); | |
-#elif MURMUR == 2 | |
- h ^= h >> 13; | |
- h *= MurmurMagic; | |
- h ^= h >> 15; | |
-#endif | |
- return h; | |
-} | |
- | |
-#define murmur_step(h, k) murmur((h), (k), 16) | |
- | |
-#if MURMUR == 1 | |
-#define murmur1(h) murmur_step((h), 16) | |
-#else | |
-#define murmur1(h) murmur_step((h), 24) | |
-#endif | |
- | |
-st_index_t | |
-st_hash(const void *ptr, size_t len, st_index_t h) | |
-{ | |
- const char *data = ptr; | |
- st_index_t t = 0; | |
- | |
- h += 0xdeadbeef; | |
- | |
-#define data_at(n) (st_index_t)((unsigned char)data[(n)]) | |
-#define UNALIGNED_ADD_4 UNALIGNED_ADD(2); UNALIGNED_ADD(1); UNALIGNED_ADD(0) | |
-#if SIZEOF_ST_INDEX_T > 4 | |
-#define UNALIGNED_ADD_8 UNALIGNED_ADD(6); UNALIGNED_ADD(5); UNALIGNED_ADD(4); UNALIGNED_ADD(3); UNALIGNED_ADD_4 | |
-#if SIZEOF_ST_INDEX_T > 8 | |
-#define UNALIGNED_ADD_16 UNALIGNED_ADD(14); UNALIGNED_ADD(13); UNALIGNED_ADD(12); UNALIGNED_ADD(11); \ | |
- UNALIGNED_ADD(10); UNALIGNED_ADD(9); UNALIGNED_ADD(8); UNALIGNED_ADD(7); UNALIGNED_ADD_8 | |
-#define UNALIGNED_ADD_ALL UNALIGNED_ADD_16 | |
-#endif | |
-#define UNALIGNED_ADD_ALL UNALIGNED_ADD_8 | |
-#else | |
-#define UNALIGNED_ADD_ALL UNALIGNED_ADD_4 | |
-#endif | |
- if (len >= sizeof(st_index_t)) { | |
-#if !UNALIGNED_WORD_ACCESS | |
- int align = (int)((st_data_t)data % sizeof(st_index_t)); | |
- if (align) { | |
- st_index_t d = 0; | |
- int sl, sr, pack; | |
- | |
- switch (align) { | |
-#ifdef WORDS_BIGENDIAN | |
-# define UNALIGNED_ADD(n) case SIZEOF_ST_INDEX_T - (n) - 1: \ | |
- t |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 2) | |
-#else | |
-# define UNALIGNED_ADD(n) case SIZEOF_ST_INDEX_T - (n) - 1: \ | |
- t |= data_at(n) << CHAR_BIT*(n) | |
-#endif | |
- UNALIGNED_ADD_ALL; | |
-#undef UNALIGNED_ADD | |
- } | |
- | |
-#ifdef WORDS_BIGENDIAN | |
- t >>= (CHAR_BIT * align) - CHAR_BIT; | |
-#else | |
- t <<= (CHAR_BIT * align); | |
-#endif | |
- | |
- data += sizeof(st_index_t)-align; | |
- len -= sizeof(st_index_t)-align; | |
- | |
- sl = CHAR_BIT * (SIZEOF_ST_INDEX_T-align); | |
- sr = CHAR_BIT * align; | |
- | |
- while (len >= sizeof(st_index_t)) { | |
- d = *(st_index_t *)data; | |
-#ifdef WORDS_BIGENDIAN | |
- t = (t << sr) | (d >> sl); | |
-#else | |
- t = (t >> sr) | (d << sl); | |
-#endif | |
- h = murmur_step(h, t); | |
- t = d; | |
- data += sizeof(st_index_t); | |
- len -= sizeof(st_index_t); | |
- } | |
- pack = len < (size_t)align ? (int)len : align; | |
- d = 0; | |
- switch (pack) { | |
-#ifdef WORDS_BIGENDIAN | |
-# define UNALIGNED_ADD(n) case (n) + 1: \ | |
- d |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 1) | |
-#else | |
-# define UNALIGNED_ADD(n) case (n) + 1: \ | |
- d |= data_at(n) << CHAR_BIT*(n) | |
-#endif | |
- UNALIGNED_ADD_ALL; | |
-#undef UNALIGNED_ADD | |
- } | |
-#ifdef WORDS_BIGENDIAN | |
- t = (t << sr) | (d >> sl); | |
-#else | |
- t = (t >> sr) | (d << sl); | |
-#endif | |
- | |
-#if MURMUR == 2 | |
- if (len < (size_t)align) goto skip_tail; | |
-#endif | |
- h = murmur_step(h, t); | |
- data += pack; | |
- len -= pack; | |
- } | |
- else | |
-#endif | |
- { | |
- do { | |
- h = murmur_step(h, *(st_index_t *)data); | |
- data += sizeof(st_index_t); | |
- len -= sizeof(st_index_t); | |
- } while (len >= sizeof(st_index_t)); | |
- } | |
- } | |
- | |
- t = 0; | |
- switch (len) { | |
-#ifdef WORDS_BIGENDIAN | |
-# define UNALIGNED_ADD(n) case (n) + 1: \ | |
- t |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 1) | |
-#else | |
-# define UNALIGNED_ADD(n) case (n) + 1: \ | |
- t |= data_at(n) << CHAR_BIT*(n) | |
-#endif | |
- UNALIGNED_ADD_ALL; | |
-#undef UNALIGNED_ADD | |
-#if MURMUR == 1 | |
- h = murmur_step(h, t); | |
-#elif MURMUR == 2 | |
-# if !UNALIGNED_WORD_ACCESS | |
- skip_tail: | |
-# endif | |
- h ^= t; | |
- h *= MurmurMagic; | |
-#endif | |
- } | |
- | |
- return murmur_finish(h); | |
-} | |
- | |
-st_index_t | |
-st_hash_uint32(st_index_t h, uint32_t i) | |
-{ | |
- return murmur_step(h + i, 16); | |
-} | |
- | |
-st_index_t | |
-st_hash_uint(st_index_t h, st_index_t i) | |
-{ | |
- st_index_t v = 0; | |
- h += i; | |
-#ifdef WORDS_BIGENDIAN | |
-#if SIZEOF_ST_INDEX_T*CHAR_BIT > 12*8 | |
- v = murmur1(v + (h >> 12*8)); | |
-#endif | |
-#if SIZEOF_ST_INDEX_T*CHAR_BIT > 8*8 | |
- v = murmur1(v + (h >> 8*8)); | |
-#endif | |
-#if SIZEOF_ST_INDEX_T*CHAR_BIT > 4*8 | |
- v = murmur1(v + (h >> 4*8)); | |
-#endif | |
-#endif | |
- v = murmur1(v + h); | |
-#ifndef WORDS_BIGENDIAN | |
-#if SIZEOF_ST_INDEX_T*CHAR_BIT > 4*8 | |
- v = murmur1(v + (h >> 4*8)); | |
-#endif | |
-#if SIZEOF_ST_INDEX_T*CHAR_BIT > 8*8 | |
- v = murmur1(v + (h >> 8*8)); | |
-#endif | |
-#if SIZEOF_ST_INDEX_T*CHAR_BIT > 12*8 | |
- v = murmur1(v + (h >> 12*8)); | |
-#endif | |
-#endif | |
- return v; | |
-} | |
- | |
-st_index_t | |
-st_hash_end(st_index_t h) | |
-{ | |
- h = murmur_step(h, 10); | |
- h = murmur_step(h, 17); | |
- return h; | |
-} | |
- | |
-#undef st_hash_start | |
-st_index_t | |
-st_hash_start(st_index_t h) | |
-{ | |
- return h; | |
-} | |
- | |
-static st_index_t | |
-strhash(st_data_t arg) | |
-{ | |
- register const char *string = (const char *)arg; | |
- return st_hash(string, strlen(string), FNV1_32A_INIT); | |
-} | |
-#endif | |
- | |
-int | |
+static int | |
st_strcasecmp(const char *s1, const char *s2) | |
{ | |
unsigned int c1, c2; | |
@@ -1276,7 +935,7 @@ | |
} | |
} | |
-int | |
+static int | |
st_strncasecmp(const char *s1, const char *s2, size_t n) | |
{ | |
unsigned int c1, c2; | |
@@ -1302,10 +961,10 @@ | |
} | |
static st_index_t | |
-strcasehash(st_data_t arg) | |
+st_internal_strcasehash(st_data_t arg) | |
{ | |
register const char *string = (const char *)arg; | |
- register st_index_t hval = FNV1_32A_INIT; | |
+ register st_index_t hval = ST_FNV1_32A_INIT; | |
/* | |
* FNV-1a hash each octet in the buffer | |
@@ -1316,19 +975,34 @@ | |
hval ^= c; | |
/* multiply by the 32 bit FNV magic prime mod 2^32 */ | |
- hval *= FNV_32_PRIME; | |
+ hval *= ST_FNV_32_PRIME; | |
} | |
return hval; | |
} | |
-int | |
+static int | |
st_numcmp(st_data_t x, st_data_t y) | |
{ | |
return x != y; | |
} | |
-st_index_t | |
+static st_index_t | |
st_numhash(st_data_t n) | |
{ | |
return (st_index_t)n; | |
} | |
+ | |
+ | |
+ | |
+#if defined __GNUC__ && __GNUC__ >= 4 | |
+#pragma GCC visibility pop | |
+#endif | |
+ | |
+#if defined(__cplusplus) | |
+#if 0 | |
+{ /* satisfy cc-mode */ | |
+#endif | |
+} /* extern "C" { */ | |
+#endif | |
+ | |
+#endif /* RUBY_ST_H */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment