Ruby 3.2.1p31 (2023-02-08 revision 31819e82c88c6f8ecfaeb162519bfa26a14b21fd)
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
19struct ar_table_struct;
20typedef unsigned char ar_hint_t;
21
22enum 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
43struct 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 */
71void rb_hash_st_table_set(VALUE hash, st_table *st);
72VALUE rb_hash_default_value(VALUE hash, VALUE key);
73VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
74long rb_dbl_long_hash(double d);
75st_table *rb_init_identtable(void);
76VALUE rb_to_hash_type(VALUE obj);
77VALUE rb_hash_key_str(VALUE);
78VALUE rb_hash_values(VALUE hash);
79VALUE rb_hash_rehash(VALUE hash);
80int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val);
81VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
82int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
83int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
84int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg);
85extern st_table *rb_hash_st_table(VALUE hash);
86VALUE rb_ident_hash_new_with_size(st_index_t size);
87
88static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h);
89static inline VALUE RHASH_IFNONE(VALUE h);
90static inline size_t RHASH_SIZE(VALUE h);
91static inline bool RHASH_EMPTY_P(VALUE h);
92static inline bool RHASH_AR_TABLE_P(VALUE h);
93static inline bool RHASH_ST_TABLE_P(VALUE h);
94static inline struct ar_table_struct *RHASH_AR_TABLE(VALUE h);
95static inline st_table *RHASH_ST_TABLE(VALUE h);
96static inline size_t RHASH_ST_SIZE(VALUE h);
97static inline void RHASH_ST_CLEAR(VALUE h);
98static inline bool RHASH_TRANSIENT_P(VALUE h);
99static inline void RHASH_SET_TRANSIENT_FLAG(VALUE h);
100static inline void RHASH_UNSET_TRANSIENT_FLAG(VALUE h);
101
102RUBY_SYMBOL_EXPORT_BEGIN
103/* hash.c (export) */
104VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
105VALUE rb_ident_hash_new(void);
106int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg);
107RUBY_SYMBOL_EXPORT_END
108
109MJIT_SYMBOL_EXPORT_BEGIN
110VALUE rb_hash_new_with_size(st_index_t size);
111VALUE rb_hash_resurrect(VALUE hash);
112int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
113VALUE rb_hash_keys(VALUE hash);
114VALUE rb_hash_has_key(VALUE hash, VALUE key);
115VALUE rb_hash_compare_by_id_p(VALUE hash);
116
117st_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__)
119MJIT_SYMBOL_EXPORT_END
120
121VALUE rb_hash_compare_by_id(VALUE hash);
122
123#if 0 /* for debug */
124
125static inline bool
126RHASH_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
132static inline struct ar_table_struct *
133RHASH_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
139static inline st_table *
140RHASH_ST_TABLE(VALUE h)
141{
142 return rb_hash_st_table(h)
143}
144
145#else
146
147static inline bool
148RHASH_AR_TABLE_P(VALUE h)
149{
150 return ! FL_TEST_RAW(h, RHASH_ST_TABLE_FLAG);
151}
152
153static inline struct ar_table_struct *
154RHASH_AR_TABLE(VALUE h)
155{
156 return RHASH(h)->as.ar;
157}
158
159static inline st_table *
160RHASH_ST_TABLE(VALUE h)
161{
162 return RHASH(h)->as.st;
163}
164
165#endif
166
167static inline VALUE
169{
170 return RHASH(h)->ifnone;
171}
172
173static inline size_t
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
184static inline bool
186{
187 return RHASH_SIZE(h) == 0;
188}
189
190static inline bool
191RHASH_ST_TABLE_P(VALUE h)
192{
193 return ! RHASH_AR_TABLE_P(h);
194}
195
196static inline size_t
197RHASH_ST_SIZE(VALUE h)
198{
199 return RHASH_ST_TABLE(h)->num_entries;
200}
201
202static inline void
203RHASH_ST_CLEAR(VALUE h)
204{
205 FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG);
206 RHASH(h)->as.ar = NULL;
207}
208
209static inline unsigned
210RHASH_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
217static inline bool
218RHASH_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
227static inline void
228RHASH_SET_TRANSIENT_FLAG(VALUE h)
229{
230#if USE_TRANSIENT_HEAP
231 FL_SET_RAW(h, RHASH_TRANSIENT_FLAG);
232#endif
233}
234
235static inline void
236RHASH_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