Ruby  3.1.4p223 (2023-03-30 revision HEAD)
hash.h
1 #ifndef INTERNAL_HASH_H /*-*-C-*-vi:se ft=c:*/
2 #define INTERNAL_HASH_H
11 #include "ruby/internal/config.h"
12 #include <stddef.h> /* for size_t */
13 #include "ruby/internal/stdbool.h" /* for bool */
14 #include "ruby/ruby.h" /* for struct RBasic */
15 #include "ruby/st.h" /* for struct st_table */
16 
17 #define RHASH_AR_TABLE_MAX_SIZE SIZEOF_VALUE
18 
19 struct ar_table_struct;
20 typedef unsigned char ar_hint_t;
21 
22 enum ruby_rhash_flags {
23  RHASH_PASS_AS_KEYWORDS = FL_USER1, /* FL 1 */
24  RHASH_PROC_DEFAULT = FL_USER2, /* FL 2 */
25  RHASH_ST_TABLE_FLAG = FL_USER3, /* FL 3 */
26  RHASH_AR_TABLE_SIZE_MASK = (FL_USER4|FL_USER5|FL_USER6|FL_USER7), /* FL 4..7 */
27  RHASH_AR_TABLE_SIZE_SHIFT = (FL_USHIFT+4),
28  RHASH_AR_TABLE_BOUND_MASK = (FL_USER8|FL_USER9|FL_USER10|FL_USER11), /* FL 8..11 */
29  RHASH_AR_TABLE_BOUND_SHIFT = (FL_USHIFT+8),
30 
31 #if USE_TRANSIENT_HEAP
32  RHASH_TRANSIENT_FLAG = FL_USER12, /* FL 12 */
33 #endif
34 
35  // we can not put it in "enum" because it can exceed "int" range.
36 #define RHASH_LEV_MASK (FL_USER13 | FL_USER14 | FL_USER15 | /* FL 13..19 */ \
37  FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19)
38 
39  RHASH_LEV_SHIFT = (FL_USHIFT + 13),
40  RHASH_LEV_MAX = 127, /* 7 bits */
41 };
42 
43 struct RHash {
44  struct RBasic basic;
45  union {
46  st_table *st;
47  struct ar_table_struct *ar; /* possibly 0 */
48  } as;
49  const VALUE ifnone;
50  union {
51  ar_hint_t ary[RHASH_AR_TABLE_MAX_SIZE];
52  VALUE word;
53  } ar_hint;
54 };
55 
56 #define RHASH(obj) ((struct RHash *)(obj))
57 
58 #ifdef RHASH_IFNONE
59 # undef RHASH_IFNONE
60 #endif
61 
62 #ifdef RHASH_SIZE
63 # undef RHASH_SIZE
64 #endif
65 
66 #ifdef RHASH_EMPTY_P
67 # undef RHASH_EMPTY_P
68 #endif
69 
70 /* hash.c */
71 void rb_hash_st_table_set(VALUE hash, st_table *st);
72 VALUE rb_hash_default_value(VALUE hash, VALUE key);
73 VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
74 long rb_dbl_long_hash(double d);
75 st_table *rb_init_identtable(void);
76 VALUE rb_to_hash_type(VALUE obj);
77 VALUE rb_hash_key_str(VALUE);
78 VALUE rb_hash_values(VALUE hash);
79 VALUE rb_hash_rehash(VALUE hash);
80 int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val);
81 VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
82 int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
83 int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
84 int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg);
85 extern st_table *rb_hash_st_table(VALUE hash);
86 VALUE rb_ident_hash_new_with_size(st_index_t size);
87 
88 static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h);
89 static inline VALUE RHASH_IFNONE(VALUE h);
90 static inline size_t RHASH_SIZE(VALUE h);
91 static inline bool RHASH_EMPTY_P(VALUE h);
92 static inline bool RHASH_AR_TABLE_P(VALUE h);
93 static inline bool RHASH_ST_TABLE_P(VALUE h);
94 static inline struct ar_table_struct *RHASH_AR_TABLE(VALUE h);
95 static inline st_table *RHASH_ST_TABLE(VALUE h);
96 static inline size_t RHASH_ST_SIZE(VALUE h);
97 static inline void RHASH_ST_CLEAR(VALUE h);
98 static inline bool RHASH_TRANSIENT_P(VALUE h);
99 static inline void RHASH_SET_TRANSIENT_FLAG(VALUE h);
100 static inline void RHASH_UNSET_TRANSIENT_FLAG(VALUE h);
101 
102 RUBY_SYMBOL_EXPORT_BEGIN
103 /* hash.c (export) */
104 VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
105 VALUE rb_ident_hash_new(void);
106 int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg);
107 RUBY_SYMBOL_EXPORT_END
108 
109 MJIT_SYMBOL_EXPORT_BEGIN
110 VALUE rb_hash_new_with_size(st_index_t size);
111 VALUE rb_hash_resurrect(VALUE hash);
112 int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
113 VALUE rb_hash_keys(VALUE hash);
114 VALUE rb_hash_has_key(VALUE hash, VALUE key);
115 VALUE rb_hash_compare_by_id_p(VALUE hash);
116 
117 st_table *rb_hash_tbl_raw(VALUE hash, const char *file, int line);
118 #define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h, __FILE__, __LINE__)
119 MJIT_SYMBOL_EXPORT_END
120 
121 VALUE rb_hash_compare_by_id(VALUE hash);
122 
123 #if 0 /* for debug */
124 
125 static inline bool
126 RHASH_AR_TABLE_P(VALUE h)
127 {
128  extern int rb_hash_ar_table_p(VALUE hash);
129  return rb_hash_ar_table_p(h)
130 }
131 
132 static inline struct ar_table_struct *
133 RHASH_AR_TABLE(VALUE h)
134 {
135  extern struct ar_table_struct *rb_hash_ar_table(VALUE hash);
136  return rb_hash_ar_table(h)
137 }
138 
139 static inline st_table *
140 RHASH_ST_TABLE(VALUE h)
141 {
142  return rb_hash_st_table(h)
143 }
144 
145 #else
146 
147 static inline bool
148 RHASH_AR_TABLE_P(VALUE h)
149 {
150  return ! FL_TEST_RAW(h, RHASH_ST_TABLE_FLAG);
151 }
152 
153 static inline struct ar_table_struct *
154 RHASH_AR_TABLE(VALUE h)
155 {
156  return RHASH(h)->as.ar;
157 }
158 
159 static inline st_table *
160 RHASH_ST_TABLE(VALUE h)
161 {
162  return RHASH(h)->as.st;
163 }
164 
165 #endif
166 
167 static inline VALUE
169 {
170  return RHASH(h)->ifnone;
171 }
172 
173 static inline size_t
174 RHASH_SIZE(VALUE h)
175 {
176  if (RHASH_AR_TABLE_P(h)) {
177  return RHASH_AR_TABLE_SIZE_RAW(h);
178  }
179  else {
180  return RHASH_ST_SIZE(h);
181  }
182 }
183 
184 static inline bool
186 {
187  return RHASH_SIZE(h) == 0;
188 }
189 
190 static inline bool
191 RHASH_ST_TABLE_P(VALUE h)
192 {
193  return ! RHASH_AR_TABLE_P(h);
194 }
195 
196 static inline size_t
197 RHASH_ST_SIZE(VALUE h)
198 {
199  return RHASH_ST_TABLE(h)->num_entries;
200 }
201 
202 static inline void
203 RHASH_ST_CLEAR(VALUE h)
204 {
205  FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG);
206  RHASH(h)->as.ar = NULL;
207 }
208 
209 static inline unsigned
210 RHASH_AR_TABLE_SIZE_RAW(VALUE h)
211 {
212  VALUE ret = FL_TEST_RAW(h, RHASH_AR_TABLE_SIZE_MASK);
213  ret >>= RHASH_AR_TABLE_SIZE_SHIFT;
214  return (unsigned)ret;
215 }
216 
217 static inline bool
218 RHASH_TRANSIENT_P(VALUE h)
219 {
220 #if USE_TRANSIENT_HEAP
221  return FL_TEST_RAW(h, RHASH_TRANSIENT_FLAG);
222 #else
223  return false;
224 #endif
225 }
226 
227 static inline void
228 RHASH_SET_TRANSIENT_FLAG(VALUE h)
229 {
230 #if USE_TRANSIENT_HEAP
231  FL_SET_RAW(h, RHASH_TRANSIENT_FLAG);
232 #endif
233 }
234 
235 static inline void
236 RHASH_UNSET_TRANSIENT_FLAG(VALUE h)
237 {
238 #if USE_TRANSIENT_HEAP
239  FL_UNSET_RAW(h, RHASH_TRANSIENT_FLAG);
240 #endif
241 }
242 
243 #endif /* INTERNAL_HASH_H */
#define FL_UNSET_RAW
Old name of RB_FL_UNSET_RAW.
Definition: fl_type.h:142
#define FL_USER3
Old name of RUBY_FL_USER3.
Definition: fl_type.h:75
#define FL_USER7
Old name of RUBY_FL_USER7.
Definition: fl_type.h:79
#define FL_USER10
Old name of RUBY_FL_USER10.
Definition: fl_type.h:82
#define FL_USER6
Old name of RUBY_FL_USER6.
Definition: fl_type.h:78
#define FL_USER1
Old name of RUBY_FL_USER1.
Definition: fl_type.h:73
#define FL_USER12
Old name of RUBY_FL_USER12.
Definition: fl_type.h:84
#define FL_USER11
Old name of RUBY_FL_USER11.
Definition: fl_type.h:83
#define FL_USER8
Old name of RUBY_FL_USER8.
Definition: fl_type.h:80
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
Definition: fl_type.h:140
#define FL_USER2
Old name of RUBY_FL_USER2.
Definition: fl_type.h:74
#define FL_USER9
Old name of RUBY_FL_USER9.
Definition: fl_type.h:81
#define FL_USER5
Old name of RUBY_FL_USER5.
Definition: fl_type.h:77
#define FL_USHIFT
Old name of RUBY_FL_USHIFT.
Definition: fl_type.h:70
#define FL_USER4
Old name of RUBY_FL_USER4.
Definition: fl_type.h:76
#define FL_SET_RAW
Old name of RB_FL_SET_RAW.
Definition: fl_type.h:138
#define RHASH_IFNONE(h)
Definition: rhash.h:72
#define RHASH_SIZE(h)
Queries the size of the hash.
Definition: rhash.h:82
#define RHASH_EMPTY_P(h)
Checks if the hash is empty.
Definition: rhash.h:92
C99 shim for <stdbool.h>
Ruby's object's, base components.
Definition: rbasic.h:64
Definition: hash.h:43
Definition: st.h:79
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40