@@ -57,77 +57,43 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
57
57
{
58
58
setentry * table ;
59
59
setentry * entry ;
60
- size_t perturb ;
60
+ size_t perturb = hash ;
61
61
size_t mask = so -> mask ;
62
62
size_t i = (size_t )hash & mask ; /* Unsigned for defined overflow behavior */
63
- size_t j ;
63
+ int probes ;
64
64
int cmp ;
65
65
66
- entry = & so -> table [i ];
67
- if (entry -> key == NULL )
68
- return entry ;
69
-
70
- perturb = hash ;
71
-
72
66
while (1 ) {
73
- if (entry -> hash == hash ) {
74
- PyObject * startkey = entry -> key ;
75
- /* startkey cannot be a dummy because the dummy hash field is -1 */
76
- assert (startkey != dummy );
77
- if (startkey == key )
78
- return entry ;
79
- if (PyUnicode_CheckExact (startkey )
80
- && PyUnicode_CheckExact (key )
81
- && _PyUnicode_EQ (startkey , key ))
82
- return entry ;
83
- table = so -> table ;
84
- Py_INCREF (startkey );
85
- cmp = PyObject_RichCompareBool (startkey , key , Py_EQ );
86
- Py_DECREF (startkey );
87
- if (cmp < 0 ) /* unlikely */
88
- return NULL ;
89
- if (table != so -> table || entry -> key != startkey ) /* unlikely */
90
- return set_lookkey (so , key , hash );
91
- if (cmp > 0 ) /* likely */
67
+ entry = & so -> table [i ];
68
+ probes = (i + LINEAR_PROBES <= mask ) ? LINEAR_PROBES : 0 ;
69
+ do {
70
+ if (entry -> hash == 0 && entry -> key == NULL )
92
71
return entry ;
93
- mask = so -> mask ; /* help avoid a register spill */
94
- }
95
-
96
- if (i + LINEAR_PROBES <= mask ) {
97
- for (j = 0 ; j < LINEAR_PROBES ; j ++ ) {
98
- entry ++ ;
99
- if (entry -> hash == 0 && entry -> key == NULL )
72
+ if (entry -> hash == hash ) {
73
+ PyObject * startkey = entry -> key ;
74
+ assert (startkey != dummy );
75
+ if (startkey == key )
100
76
return entry ;
101
- if (entry -> hash == hash ) {
102
- PyObject * startkey = entry -> key ;
103
- assert (startkey != dummy );
104
- if (startkey == key )
105
- return entry ;
106
- if (PyUnicode_CheckExact (startkey )
107
- && PyUnicode_CheckExact (key )
108
- && _PyUnicode_EQ (startkey , key ))
109
- return entry ;
110
- table = so -> table ;
111
- Py_INCREF (startkey );
112
- cmp = PyObject_RichCompareBool (startkey , key , Py_EQ );
113
- Py_DECREF (startkey );
114
- if (cmp < 0 )
115
- return NULL ;
116
- if (table != so -> table || entry -> key != startkey )
117
- return set_lookkey (so , key , hash );
118
- if (cmp > 0 )
119
- return entry ;
120
- mask = so -> mask ;
121
- }
77
+ if (PyUnicode_CheckExact (startkey )
78
+ && PyUnicode_CheckExact (key )
79
+ && _PyUnicode_EQ (startkey , key ))
80
+ return entry ;
81
+ table = so -> table ;
82
+ Py_INCREF (startkey );
83
+ cmp = PyObject_RichCompareBool (startkey , key , Py_EQ );
84
+ Py_DECREF (startkey );
85
+ if (cmp < 0 )
86
+ return NULL ;
87
+ if (table != so -> table || entry -> key != startkey )
88
+ return set_lookkey (so , key , hash );
89
+ if (cmp > 0 )
90
+ return entry ;
91
+ mask = so -> mask ;
122
92
}
123
- }
124
-
93
+ entry ++ ;
94
+ } while ( probes -- );
125
95
perturb >>= PERTURB_SHIFT ;
126
96
i = (i * 5 + 1 + perturb ) & mask ;
127
-
128
- entry = & so -> table [i ];
129
- if (entry -> key == NULL )
130
- return entry ;
131
97
}
132
98
}
133
99
@@ -141,7 +107,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
141
107
size_t perturb ;
142
108
size_t mask ;
143
109
size_t i ; /* Unsigned for defined overflow behavior */
144
- size_t j ;
110
+ int probes ;
145
111
int cmp ;
146
112
147
113
/* Pre-increment is necessary to prevent arbitrary code in the rich
@@ -152,75 +118,39 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
152
118
153
119
mask = so -> mask ;
154
120
i = (size_t )hash & mask ;
155
-
156
- entry = & so -> table [i ];
157
- if (entry -> key == NULL )
158
- goto found_unused ;
159
-
160
121
perturb = hash ;
161
122
162
123
while (1 ) {
163
- if (entry -> hash == hash ) {
164
- PyObject * startkey = entry -> key ;
165
- /* startkey cannot be a dummy because the dummy hash field is -1 */
166
- assert (startkey != dummy );
167
- if (startkey == key )
168
- goto found_active ;
169
- if (PyUnicode_CheckExact (startkey )
170
- && PyUnicode_CheckExact (key )
171
- && _PyUnicode_EQ (startkey , key ))
172
- goto found_active ;
173
- table = so -> table ;
174
- Py_INCREF (startkey );
175
- cmp = PyObject_RichCompareBool (startkey , key , Py_EQ );
176
- Py_DECREF (startkey );
177
- if (cmp > 0 ) /* likely */
178
- goto found_active ;
179
- if (cmp < 0 )
180
- goto comparison_error ;
181
- /* Continuing the search from the current entry only makes
182
- sense if the table and entry are unchanged; otherwise,
183
- we have to restart from the beginning */
184
- if (table != so -> table || entry -> key != startkey )
185
- goto restart ;
186
- mask = so -> mask ; /* help avoid a register spill */
187
- }
188
-
189
- if (i + LINEAR_PROBES <= mask ) {
190
- for (j = 0 ; j < LINEAR_PROBES ; j ++ ) {
191
- entry ++ ;
192
- if (entry -> hash == 0 && entry -> key == NULL )
193
- goto found_unused ;
194
- if (entry -> hash == hash ) {
195
- PyObject * startkey = entry -> key ;
196
- assert (startkey != dummy );
197
- if (startkey == key )
198
- goto found_active ;
199
- if (PyUnicode_CheckExact (startkey )
200
- && PyUnicode_CheckExact (key )
201
- && _PyUnicode_EQ (startkey , key ))
202
- goto found_active ;
203
- table = so -> table ;
204
- Py_INCREF (startkey );
205
- cmp = PyObject_RichCompareBool (startkey , key , Py_EQ );
206
- Py_DECREF (startkey );
207
- if (cmp > 0 )
208
- goto found_active ;
209
- if (cmp < 0 )
210
- goto comparison_error ;
211
- if (table != so -> table || entry -> key != startkey )
212
- goto restart ;
213
- mask = so -> mask ;
214
- }
124
+ entry = & so -> table [i ];
125
+ probes = (i + LINEAR_PROBES <= mask ) ? LINEAR_PROBES : 0 ;
126
+ do {
127
+ if (entry -> hash == 0 && entry -> key == NULL )
128
+ goto found_unused ;
129
+ if (entry -> hash == hash ) {
130
+ PyObject * startkey = entry -> key ;
131
+ assert (startkey != dummy );
132
+ if (startkey == key )
133
+ goto found_active ;
134
+ if (PyUnicode_CheckExact (startkey )
135
+ && PyUnicode_CheckExact (key )
136
+ && _PyUnicode_EQ (startkey , key ))
137
+ goto found_active ;
138
+ table = so -> table ;
139
+ Py_INCREF (startkey );
140
+ cmp = PyObject_RichCompareBool (startkey , key , Py_EQ );
141
+ Py_DECREF (startkey );
142
+ if (cmp > 0 )
143
+ goto found_active ;
144
+ if (cmp < 0 )
145
+ goto comparison_error ;
146
+ if (table != so -> table || entry -> key != startkey )
147
+ goto restart ;
148
+ mask = so -> mask ;
215
149
}
216
- }
217
-
150
+ entry ++ ;
151
+ } while ( probes -- );
218
152
perturb >>= PERTURB_SHIFT ;
219
153
i = (i * 5 + 1 + perturb ) & mask ;
220
-
221
- entry = & so -> table [i ];
222
- if (entry -> key == NULL )
223
- goto found_unused ;
224
154
}
225
155
226
156
found_unused :
0 commit comments