Ruby 4.1.0dev (2026-09-21 revision 61de3dd727146cfcf24e8051595bb2fb842f37aa)
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 RHASH_COMPARE_BY_IDENTITY = FL_USER12, /* FL 12 */
31
32 // we can not put it in "enum" because it can exceed "int" range.
33#define RHASH_LEV_MASK (FL_USER13 | FL_USER14 | FL_USER15 | /* FL 13..19 */ \
34 FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19)
35
36 RHASH_LEV_SHIFT = (FL_USHIFT + 13),
37 RHASH_LEV_MAX = 127, /* 7 bits */
38};
39
40typedef struct ar_table_pair_struct {
41 VALUE key;
42 VALUE val;
44
45typedef struct ar_table_struct {
46 union {
47 ar_hint_t ary[RHASH_AR_TABLE_MAX_SIZE];
48 VALUE word;
49 } ar_hint;
50 /* 64bit CPU: 8B * 2 * 8 = 128B */
51 ar_table_pair pairs[RHASH_AR_TABLE_MAX_SIZE];
52} ar_table;
53
54struct RHash {
55 struct RBasic basic;
56 const VALUE ifnone;
57};
58
59#define RHASH(obj) ((struct RHash *)(obj))
60
61#ifdef RHASH_IFNONE
62# undef RHASH_IFNONE
63#endif
64
65#ifdef RHASH_SIZE
66# undef RHASH_SIZE
67#endif
68
69#ifdef RHASH_EMPTY_P
70# undef RHASH_EMPTY_P
71#endif
72
73/* hash.c */
74VALUE rb_hash_default_value(VALUE hash, VALUE key);
75VALUE rb_hash_set_default(VALUE hash, VALUE ifnone);
76VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
77long rb_dbl_long_hash(double d);
78st_table *rb_init_identtable(void);
79st_index_t rb_any_hash(VALUE a);
80int rb_any_cmp(VALUE a, VALUE b);
81VALUE rb_to_hash_type(VALUE obj);
82VALUE rb_hash_key_str(VALUE);
83VALUE rb_hash_values(VALUE hash);
84VALUE rb_hash_rehash(VALUE hash);
85int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val);
86VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
87int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
88int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg);
89bool rb_hash_default_unredefined(VALUE hash);
90VALUE rb_hash_alloc_fixed_size(VALUE klass, st_index_t size);
91VALUE rb_ident_hash_new_capa(long size);
92void rb_hash_free(VALUE hash);
93VALUE rb_hash_alloc_copy(VALUE klass, VALUE src);
94RUBY_EXTERN VALUE rb_cHash_empty_frozen;
95
96static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h);
97static inline VALUE RHASH_IFNONE(VALUE h);
98static inline size_t RHASH_SIZE(VALUE h);
99static inline bool RHASH_EMPTY_P(VALUE h);
100static inline bool RHASH_AR_TABLE_P(VALUE h);
101static inline bool RHASH_ST_TABLE_P(VALUE h);
102static inline struct ar_table_struct *RHASH_AR_TABLE(VALUE h);
103static inline st_table *RHASH_ST_TABLE(VALUE h);
104static inline size_t RHASH_ST_SIZE(VALUE h);
105static inline void RHASH_ST_CLEAR(VALUE h);
106
107RUBY_SYMBOL_EXPORT_BEGIN
108/* hash.c (export) */
109VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
110VALUE rb_ident_hash_new(void);
111int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg);
112int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
113RUBY_SYMBOL_EXPORT_END
114
115VALUE rb_hash_new_with_bulk_insert(long argc, const VALUE *argv);
116VALUE rb_hash_merge2(VALUE h1, VALUE h2, bool dup);
117VALUE rb_hash_merge2_bulk(VALUE hash, long argc, const VALUE *argv, bool dup);
118VALUE rb_hash_resurrect(VALUE hash);
119int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
120VALUE rb_hash_keys(VALUE hash);
121VALUE rb_hash_has_key(VALUE hash, VALUE key);
122VALUE rb_hash_compare_by_id_p(VALUE hash);
123
124st_table *rb_hash_tbl_raw(VALUE hash, const char *file, int line);
125#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h, __FILE__, __LINE__)
126
127VALUE rb_hash_compare_by_id(VALUE hash);
128
129static inline bool
130RHASH_AR_TABLE_P(VALUE h)
131{
132 return ! FL_TEST_RAW(h, RHASH_ST_TABLE_FLAG);
133}
134
136static inline struct ar_table_struct *
137RHASH_AR_TABLE(VALUE h)
138{
139 return (struct ar_table_struct *)((uintptr_t)h + sizeof(struct RHash));
140}
141
143static inline st_table *
144RHASH_ST_TABLE(VALUE h)
145{
146 return (st_table *)((uintptr_t)h + sizeof(struct RHash));
147}
148
149static inline VALUE
151{
152 return RHASH(h)->ifnone;
153}
154
155static inline size_t
157{
158 if (RHASH_AR_TABLE_P(h)) {
159 return RHASH_AR_TABLE_SIZE_RAW(h);
160 }
161 else {
162 return RHASH_ST_SIZE(h);
163 }
164}
165
166static inline bool
168{
169 return RHASH_SIZE(h) == 0;
170}
171
172static inline bool
173RHASH_ST_TABLE_P(VALUE h)
174{
175 return ! RHASH_AR_TABLE_P(h);
176}
177
178static inline size_t
179RHASH_ST_SIZE(VALUE h)
180{
181 return RHASH_ST_TABLE(h)->num_entries;
182}
183
184static inline void
185RHASH_ST_CLEAR(VALUE h)
186{
187 memset(RHASH_ST_TABLE(h), 0, sizeof(st_table));
188}
189
190static inline unsigned
191RHASH_AR_TABLE_SIZE_RAW(VALUE h)
192{
193 VALUE ret = FL_TEST_RAW(h, RHASH_AR_TABLE_SIZE_MASK);
194 ret >>= RHASH_AR_TABLE_SIZE_SHIFT;
195 return (unsigned)ret;
196}
197
198#define RHASH_AR_TABLE_BOUND_RAW(h) \
199 ((unsigned int)((RBASIC(h)->flags >> RHASH_AR_TABLE_BOUND_SHIFT) & \
200 (RHASH_AR_TABLE_BOUND_MASK >> RHASH_AR_TABLE_BOUND_SHIFT)))
201
202
203static inline unsigned int
204RHASH_AR_TABLE_BOUND(VALUE h)
205{
206 RUBY_ASSERT(RHASH_AR_TABLE_P(h));
207 const unsigned int bound = RHASH_AR_TABLE_BOUND_RAW(h);
208 RBIMPL_ASSERT_OR_ASSUME(bound <= RHASH_AR_TABLE_MAX_SIZE);
209 return bound;
210}
211
212#define RHASH_ST_SLOT_SIZE (sizeof(struct RHash) + sizeof(st_table))
213
214static inline size_t
215RHASH_AR_SLOT_SIZE(size_t capa)
216{
217 return sizeof(struct RHash) + offsetof(ar_table, pairs) + capa * sizeof(ar_table_pair);
218}
219
220#endif /* INTERNAL_HASH_H */
#define RBIMPL_ASSERT_OR_ASSUME(...)
This is either RUBY_ASSERT or RBIMPL_ASSUME, depending on RUBY_DEBUG.
Definition assert.h:311
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
Definition assert.h:219
#define RUBY_EXTERN
Declaration of externally visible global variables.
Definition dllexport.h:45
#define FL_USER3
Old name of RUBY_FL_USER3.
Definition fl_type.h:72
#define FL_USER7
Old name of RUBY_FL_USER7.
Definition fl_type.h:76
#define FL_USER10
Old name of RUBY_FL_USER10.
Definition fl_type.h:79
#define FL_USER6
Old name of RUBY_FL_USER6.
Definition fl_type.h:75
#define FL_USER1
Old name of RUBY_FL_USER1.
Definition fl_type.h:70
#define FL_USER12
Old name of RUBY_FL_USER12.
Definition fl_type.h:81
#define FL_USER11
Old name of RUBY_FL_USER11.
Definition fl_type.h:80
#define FL_USER8
Old name of RUBY_FL_USER8.
Definition fl_type.h:77
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
Definition fl_type.h:128
#define FL_USER2
Old name of RUBY_FL_USER2.
Definition fl_type.h:71
#define FL_USER9
Old name of RUBY_FL_USER9.
Definition fl_type.h:78
#define FL_USER5
Old name of RUBY_FL_USER5.
Definition fl_type.h:74
#define FL_USHIFT
Old name of RUBY_FL_USHIFT.
Definition fl_type.h:67
#define FL_USER4
Old name of RUBY_FL_USER4.
Definition fl_type.h:73
int capa
Designed capacity of the buffer.
Definition io.h:11
#define RBIMPL_ATTR_RETURNS_NONNULL()
Wraps (or simulates) __attribute__((returns_nonnull))
#define RHASH_IFNONE(h)
Definition rhash.h:59
#define RHASH_SIZE(h)
Queries the size of the hash.
Definition rhash.h:69
#define RHASH_EMPTY_P(h)
Checks if the hash is empty.
Definition rhash.h:79
C99 shim for <stdbool.h>
Ruby object's base components.
Definition rbasic.h:69
const VALUE klass
Class of an object.
Definition rbasic.h:92
Definition hash.h:54
Definition st.h:79
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40