1/* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */ 2 3/* @(#) st.h 5.1 89/12/14 */ 4 5#ifndef RUBY_ST_H 6#define RUBY_ST_H 1 7 8#if defined(__cplusplus) 9extern "C" { 10#if 0 11} /* satisfy cc-mode */ 12#endif 13#endif 14 15#include "ruby/defines.h" 16 17#if defined STDC_HEADERS 18#include <stddef.h> 19#elif defined HAVE_STDLIB_H 20#include <stdlib.h> 21#endif 22 23#ifdef HAVE_STDINT_H 24# include <stdint.h> 25#endif 26#ifdef HAVE_INTTYPES_H 27# include <inttypes.h> 28#endif 29 30#if defined __GNUC__ && __GNUC__ >= 4 31#pragma GCC visibility push(default) 32#endif 33 34#if SIZEOF_LONG == SIZEOF_VOIDP 35typedef unsigned long st_data_t; 36#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP 37typedef unsigned LONG_LONG st_data_t; 38#else 39# error ---->> st.c requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<---- 40#endif 41#define ST_DATA_T_DEFINED 42 43#ifndef CHAR_BIT 44# ifdef HAVE_LIMITS_H 45# include <limits.h> 46# else 47# define CHAR_BIT 8 48# endif 49#endif 50#ifndef _ 51# define _(args) args 52#endif 53#ifndef ANYARGS 54# ifdef __cplusplus 55# define ANYARGS ... 56# else 57# define ANYARGS 58# endif 59#endif 60 61typedef struct st_table st_table; 62 63typedef st_data_t st_index_t; 64typedef int st_compare_func(st_data_t, st_data_t); 65typedef st_index_t st_hash_func(st_data_t); 66 67typedef char st_check_for_sizeof_st_index_t[SIZEOF_VOIDP == (int)sizeof(st_index_t) ? 1 : -1]; 68#define SIZEOF_ST_INDEX_T SIZEOF_VOIDP 69 70struct st_hash_type { 71 int (*compare)(ANYARGS /*st_data_t, st_data_t*/); /* st_compare_func* */ 72 st_index_t (*hash)(ANYARGS /*st_data_t*/); /* st_hash_func* */ 73}; 74 75#define ST_INDEX_BITS (sizeof(st_index_t) * CHAR_BIT) 76 77struct st_table { 78 const struct st_hash_type *type; 79 st_index_t num_bins; 80 unsigned int entries_packed : 1; 81#ifdef __GNUC__ 82 /* 83 * C spec says, 84 * A bit-field shall have a type that is a qualified or unqualified 85 * version of _Bool, signed int, unsigned int, or some other 86 * implementation-defined type. It is implementation-defined whether 87 * atomic types are permitted. 88 * In short, long and long long bit-field are implementation-defined 89 * feature. Therefore we want to supress a warning explicitly. 90 */ 91 __extension__ 92#endif 93 st_index_t num_entries : ST_INDEX_BITS - 1; 94 union { 95 struct { 96 struct st_table_entry **bins; 97 struct st_table_entry *head, *tail; 98 } big; 99 struct { 100 struct st_packed_entry *entries; 101 st_index_t real_entries; 102 } packed; 103 } as; 104}; 105 106#define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0) 107 108enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK}; 109 110st_table *st_init_table(const struct st_hash_type *); 111st_table *st_init_table_with_size(const struct st_hash_type *, st_index_t); 112st_table *st_init_numtable(void); 113st_table *st_init_numtable_with_size(st_index_t); 114st_table *st_init_strtable(void); 115st_table *st_init_strtable_with_size(st_index_t); 116st_table *st_init_strcasetable(void); 117st_table *st_init_strcasetable_with_size(st_index_t); 118int st_delete(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */ 119int st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t); 120int st_insert(st_table *, st_data_t, st_data_t); 121int st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t)); 122int st_lookup(st_table *, st_data_t, st_data_t *); 123int st_get_key(st_table *, st_data_t, st_data_t *); 124typedef int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing); 125int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg); 126int st_foreach(st_table *, int (*)(ANYARGS), st_data_t); 127int st_foreach_check(st_table *, int (*)(ANYARGS), st_data_t, st_data_t); 128int st_reverse_foreach(st_table *, int (*)(ANYARGS), st_data_t); 129void st_add_direct(st_table *, st_data_t, st_data_t); 130void st_free_table(st_table *); 131void st_cleanup_safe(st_table *, st_data_t); 132void st_clear(st_table *); 133st_table *st_copy(st_table *); 134int st_numcmp(st_data_t, st_data_t); 135st_index_t st_numhash(st_data_t); 136int st_strcasecmp(const char *s1, const char *s2); 137int st_strncasecmp(const char *s1, const char *s2, size_t n); 138size_t st_memsize(const st_table *); 139st_index_t st_hash(const void *ptr, size_t len, st_index_t h); 140st_index_t st_hash_uint32(st_index_t h, uint32_t i); 141st_index_t st_hash_uint(st_index_t h, st_index_t i); 142st_index_t st_hash_end(st_index_t h); 143st_index_t st_hash_start(st_index_t h); 144#define st_hash_start(h) ((st_index_t)(h)) 145 146#if defined __GNUC__ && __GNUC__ >= 4 147#pragma GCC visibility pop 148#endif 149 150#if defined(__cplusplus) 151#if 0 152{ /* satisfy cc-mode */ 153#endif 154} /* extern "C" { */ 155#endif 156 157#endif /* RUBY_ST_H */ 158