@@ -57,77 +57,43 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
5757{
5858 setentry  * table ;
5959 setentry  * entry ;
60-  size_t  perturb ;
60+  size_t  perturb   =   hash ;
6161 size_t  mask  =  so -> mask ;
6262 size_t  i  =  (size_t )hash  &  mask ; /* Unsigned for defined overflow behavior */ 
63-  size_t   j ;
63+  int   probes ;
6464 int  cmp ;
6565
66-  entry  =  & so -> table [i ];
67-  if  (entry -> key  ==  NULL )
68-  return  entry ;
69- 
70-  perturb  =  hash ;
71- 
7266 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 )
9271 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 )
10076 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 ;
12292 }
123-  } 
124- 
93+    entry ++ ; 
94+  }  while  ( probes -- ); 
12595 perturb  >>= PERTURB_SHIFT ;
12696 i  =  (i  *  5  +  1  +  perturb ) &  mask ;
127- 
128-  entry  =  & so -> table [i ];
129-  if  (entry -> key  ==  NULL )
130-  return  entry ;
13197 }
13298}
13399
@@ -141,7 +107,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
141107 size_t  perturb ;
142108 size_t  mask ;
143109 size_t  i ; /* Unsigned for defined overflow behavior */ 
144-  size_t   j ;
110+  int   probes ;
145111 int  cmp ;
146112
147113 /* 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)
152118
153119 mask  =  so -> mask ;
154120 i  =  (size_t )hash  &  mask ;
155- 
156-  entry  =  & so -> table [i ];
157-  if  (entry -> key  ==  NULL )
158-  goto found_unused ;
159- 
160121 perturb  =  hash ;
161122
162123 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 ;
215149 }
216-  } 
217- 
150+    entry ++ ; 
151+  }  while  ( probes -- ); 
218152 perturb  >>= PERTURB_SHIFT ;
219153 i  =  (i  *  5  +  1  +  perturb ) &  mask ;
220- 
221-  entry  =  & so -> table [i ];
222-  if  (entry -> key  ==  NULL )
223-  goto found_unused ;
224154 }
225155
226156 found_unused :
0 commit comments