Ruby  3.4.0dev (2024-11-22 revision 0989400a925cd201defdca9eb28eb87200b30785)
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  // we can not put it in "enum" because it can exceed "int" range.
32 #define RHASH_LEV_MASK (FL_USER13 | FL_USER14 | FL_USER15 | /* FL 13..19 */ \
33  FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19)
34 
35  RHASH_LEV_SHIFT = (FL_USHIFT + 13),
36  RHASH_LEV_MAX = 127, /* 7 bits */
37 };
38 
39 typedef struct ar_table_pair_struct {
40  VALUE key;
41  VALUE val;
43 
44 typedef struct ar_table_struct {
45  union {
46  ar_hint_t ary[RHASH_AR_TABLE_MAX_SIZE];
47  VALUE word;
48  } ar_hint;
49  /* 64bit CPU: 8B * 2 * 8 = 128B */
50  ar_table_pair pairs[RHASH_AR_TABLE_MAX_SIZE];
51 } ar_table;
52 
53 struct RHash {
54  struct RBasic basic;
55  const VALUE ifnone;
56 };
57 
58 #define RHASH(obj) ((struct RHash *)(obj))
59 
60 #ifdef RHASH_IFNONE
61 # undef RHASH_IFNONE
62 #endif
63 
64 #ifdef RHASH_SIZE
65 # undef RHASH_SIZE
66 #endif
67 
68 #ifdef RHASH_EMPTY_P
69 # undef RHASH_EMPTY_P
70 #endif
71 
72 /* hash.c */
73 void rb_hash_st_table_set(VALUE hash, st_table *st);
74 VALUE rb_hash_default_value(VALUE hash, VALUE key);
75 VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
76 long rb_dbl_long_hash(double d);
77 st_table *rb_init_identtable(void);
78 st_index_t rb_any_hash(VALUE a);
79 int rb_any_cmp(VALUE a, VALUE b);
80 VALUE rb_to_hash_type(VALUE obj);
81 VALUE rb_hash_key_str(VALUE);
82 VALUE rb_hash_values(VALUE hash);
83 VALUE rb_hash_rehash(VALUE hash);
84 int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val);
85 VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
86 int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
87 int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
88 int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg);
89 VALUE rb_ident_hash_new_with_size(st_index_t size);
90 void rb_hash_free(VALUE hash);
91 RUBY_EXTERN VALUE rb_cHash_empty_frozen;
92 
93 static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h);
94 static inline VALUE RHASH_IFNONE(VALUE h);
95 static inline size_t RHASH_SIZE(VALUE h);
96 static inline bool RHASH_EMPTY_P(VALUE h);
97 static inline bool RHASH_AR_TABLE_P(VALUE h);
98 static inline bool RHASH_ST_TABLE_P(VALUE h);
99 static inline struct ar_table_struct *RHASH_AR_TABLE(VALUE h);
100 static inline st_table *RHASH_ST_TABLE(VALUE h);
101 static inline size_t RHASH_ST_SIZE(VALUE h);
102 static inline void RHASH_ST_CLEAR(VALUE h);
103 
104 RUBY_SYMBOL_EXPORT_BEGIN
105 /* hash.c (export) */
106 VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
107 VALUE rb_ident_hash_new(void);
108 int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg);
109 RUBY_SYMBOL_EXPORT_END
110 
111 VALUE rb_hash_new_with_size(st_index_t size);
112 VALUE rb_hash_resurrect(VALUE hash);
113 int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
114 VALUE rb_hash_keys(VALUE hash);
115 VALUE rb_hash_has_key(VALUE hash, VALUE key);
116 VALUE rb_hash_compare_by_id_p(VALUE hash);
117 
118 st_table *rb_hash_tbl_raw(VALUE hash, const char *file, int line);
119 #define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h, __FILE__, __LINE__)
120 
121 VALUE rb_hash_compare_by_id(VALUE hash);
122 
123 static inline bool
124 RHASH_AR_TABLE_P(VALUE h)
125 {
126  return ! FL_TEST_RAW(h, RHASH_ST_TABLE_FLAG);
127 }
128 
130 static inline struct ar_table_struct *
131 RHASH_AR_TABLE(VALUE h)
132 {
133  return (struct ar_table_struct *)((uintptr_t)h + sizeof(struct RHash));
134 }
135 
137 static inline st_table *
138 RHASH_ST_TABLE(VALUE h)
139 {
140  return (st_table *)((uintptr_t)h + sizeof(struct RHash));
141 }
142 
143 static inline VALUE
145 {
146  return RHASH(h)->ifnone;
147 }
148 
149 static inline size_t
150 RHASH_SIZE(VALUE h)
151 {
152  if (RHASH_AR_TABLE_P(h)) {
153  return RHASH_AR_TABLE_SIZE_RAW(h);
154  }
155  else {
156  return RHASH_ST_SIZE(h);
157  }
158 }
159 
160 static inline bool
162 {
163  return RHASH_SIZE(h) == 0;
164 }
165 
166 static inline bool
167 RHASH_ST_TABLE_P(VALUE h)
168 {
169  return ! RHASH_AR_TABLE_P(h);
170 }
171 
172 static inline size_t
173 RHASH_ST_SIZE(VALUE h)
174 {
175  return RHASH_ST_TABLE(h)->num_entries;
176 }
177 
178 static inline void
179 RHASH_ST_CLEAR(VALUE h)
180 {
181  memset(RHASH_ST_TABLE(h), 0, sizeof(st_table));
182 }
183 
184 static inline unsigned
185 RHASH_AR_TABLE_SIZE_RAW(VALUE h)
186 {
187  VALUE ret = FL_TEST_RAW(h, RHASH_AR_TABLE_SIZE_MASK);
188  ret >>= RHASH_AR_TABLE_SIZE_SHIFT;
189  return (unsigned)ret;
190 }
191 
192 #endif /* INTERNAL_HASH_H */
#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:74
#define FL_USER7
Old name of RUBY_FL_USER7.
Definition: fl_type.h:78
#define FL_USER10
Old name of RUBY_FL_USER10.
Definition: fl_type.h:81
#define FL_USER6
Old name of RUBY_FL_USER6.
Definition: fl_type.h:77
#define FL_USER1
Old name of RUBY_FL_USER1.
Definition: fl_type.h:72
#define FL_USER11
Old name of RUBY_FL_USER11.
Definition: fl_type.h:82
#define FL_USER8
Old name of RUBY_FL_USER8.
Definition: fl_type.h:79
#define FL_TEST_RAW
Old name of RB_FL_TEST_RAW.
Definition: fl_type.h:132
#define FL_USER2
Old name of RUBY_FL_USER2.
Definition: fl_type.h:73
#define FL_USER9
Old name of RUBY_FL_USER9.
Definition: fl_type.h:80
#define FL_USER5
Old name of RUBY_FL_USER5.
Definition: fl_type.h:76
#define FL_USHIFT
Old name of RUBY_FL_USHIFT.
Definition: fl_type.h:69
#define FL_USER4
Old name of RUBY_FL_USER4.
Definition: fl_type.h:75
#define inline
Old Visual Studio versions do not support the inline keyword, so we need to define it to be __inline.
Definition: defines.h:88
#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:63
Definition: hash.h:53
Definition: st.h:79
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40