Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit afe8909

Browse files
committed
Tighten-up the lookkey() logic and beautify the code a bit.
Use less code by moving many of the steps from the initial lookup into the main search loop. Beautify the code but keep the overall logic unchanged.
1 parent 7c1017b commit afe8909

1 file changed

Lines changed: 43 additions & 88 deletions

File tree

Objects/setobject.c

Lines changed: 43 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -79,101 +79,66 @@ NULL if the rich comparison returns an error.
7979
static setentry *
8080
set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
8181
{
82-
size_t i, j; /* Unsigned for defined overflow behavior. */
83-
size_t perturb;
84-
setentry *freeslot;
85-
size_t mask = so->mask;
8682
setentry *table = so->table;
83+
setentry *freeslot = NULL;
8784
setentry *entry;
85+
size_t perturb = hash;
86+
size_t mask = so->mask;
87+
size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior. */
88+
size_t j = i;
8889
int cmp;
89-
PyObject *startkey;
9090

91-
i = (size_t)hash & mask;
9291
entry = &table[i];
93-
if (entry->key == NULL || entry->key == key)
92+
if (entry->key == NULL)
9493
return entry;
95-
if (entry->hash == hash && entry->key != dummy) {
96-
startkey = entry->key;
97-
Py_INCREF(startkey);
98-
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
99-
Py_DECREF(startkey);
100-
if (cmp < 0)
101-
return NULL;
102-
if (table == so->table && entry->key == startkey) {
103-
if (cmp > 0)
104-
return entry;
105-
}
106-
else {
107-
/* Start over if the compare altered the set */
108-
return set_lookkey(so, key, hash);
109-
}
110-
}
111-
freeslot = (entry->key == dummy) ? entry : NULL;
11294

113-
/* In the loop, key == dummy is by far (factor of 100s)
114-
the least likely outcome, so test for that last. */
115-
j = i;
116-
perturb = hash;
11795
while (1) {
118-
j ^= 1;
119-
entry = &table[j];
120-
if (entry->key == NULL) {
121-
if (freeslot != NULL)
122-
entry = freeslot;
123-
break;
124-
}
12596
if (entry->key == key)
126-
break;
97+
return entry;
12798
if (entry->hash == hash && entry->key != dummy) {
128-
startkey = entry->key;
99+
PyObject *startkey = entry->key;
129100
Py_INCREF(startkey);
130101
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
131102
Py_DECREF(startkey);
132103
if (cmp < 0)
133104
return NULL;
134-
if (table == so->table && entry->key == startkey) {
135-
if (cmp > 0)
136-
break;
137-
}
138-
else {
105+
if (table != so->table || entry->key != startkey)
139106
return set_lookkey(so, key, hash);
140-
}
107+
if (cmp > 0)
108+
return entry;
141109
}
142110
if (entry->key == dummy && freeslot == NULL)
143111
freeslot = entry;
144112

145-
i = i * 5 + perturb + 1;
146-
j = i & mask;
147-
perturb >>= PERTURB_SHIFT;
148-
149-
entry = &table[j];
150-
if (entry->key == NULL) {
151-
if (freeslot != NULL)
152-
entry = freeslot;
113+
entry = &table[j ^ 1];
114+
if (entry->key == NULL)
153115
break;
154-
}
155116
if (entry->key == key)
156-
break;
117+
return entry;
157118
if (entry->hash == hash && entry->key != dummy) {
158-
startkey = entry->key;
119+
PyObject *startkey = entry->key;
159120
Py_INCREF(startkey);
160121
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
161122
Py_DECREF(startkey);
162123
if (cmp < 0)
163124
return NULL;
164-
if (table == so->table && entry->key == startkey) {
165-
if (cmp > 0)
166-
break;
167-
}
168-
else {
125+
if (table != so->table || entry->key != startkey)
169126
return set_lookkey(so, key, hash);
170-
}
127+
if (cmp > 0)
128+
return entry;
171129
}
172130
if (entry->key == dummy && freeslot == NULL)
173131
freeslot = entry;
174132

133+
i = i * 5 + perturb + 1;
134+
j = i & mask;
135+
perturb >>= PERTURB_SHIFT;
136+
137+
entry = &table[j];
138+
if (entry->key == NULL)
139+
break;
175140
}
176-
return entry;
141+
return freeslot == NULL ? entry : freeslot;
177142
}
178143

179144
/*
@@ -184,12 +149,13 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
184149
static setentry *
185150
set_lookkey_unicode(PySetObject *so, PyObject *key, Py_hash_t hash)
186151
{
187-
size_t i, j; /* Unsigned for defined overflow behavior. */
188-
size_t perturb;
189-
setentry *freeslot;
190-
size_t mask = so->mask;
191152
setentry *table = so->table;
153+
setentry *freeslot = NULL;
192154
setentry *entry;
155+
size_t perturb = hash;
156+
size_t mask = so->mask;
157+
size_t i = (size_t)hash & mask;
158+
size_t j = i;
193159

194160
/* Make sure this function doesn't have to handle non-unicode keys,
195161
including subclasses of str; e.g., one reason to subclass
@@ -200,25 +166,11 @@ set_lookkey_unicode(PySetObject *so, PyObject *key, Py_hash_t hash)
200166
return set_lookkey(so, key, hash);
201167
}
202168

203-
i = (size_t)hash & mask;
204169
entry = &table[i];
205-
if (entry->key == NULL || entry->key == key)
170+
if (entry->key == NULL)
206171
return entry;
207-
if (entry->key == dummy)
208-
freeslot = entry;
209-
else {
210-
if (entry->hash == hash && unicode_eq(entry->key, key))
211-
return entry;
212-
freeslot = NULL;
213-
}
214172

215-
j = i;
216-
perturb = hash;
217173
while (1) {
218-
j ^= 1;
219-
entry = &table[j];
220-
if (entry->key == NULL)
221-
return freeslot == NULL ? entry : freeslot;
222174
if (entry->key == key
223175
|| (entry->hash == hash
224176
&& entry->key != dummy
@@ -227,23 +179,26 @@ set_lookkey_unicode(PySetObject *so, PyObject *key, Py_hash_t hash)
227179
if (entry->key == dummy && freeslot == NULL)
228180
freeslot = entry;
229181

230-
i = i * 5 + perturb + 1;
231-
j = i & mask;
232-
perturb >>= PERTURB_SHIFT;
233-
234-
entry = &table[j];
182+
entry = &table[j ^ 1];
235183
if (entry->key == NULL)
236-
return freeslot == NULL ? entry : freeslot;
184+
break;
237185
if (entry->key == key
238186
|| (entry->hash == hash
239187
&& entry->key != dummy
240188
&& unicode_eq(entry->key, key)))
241189
return entry;
242190
if (entry->key == dummy && freeslot == NULL)
243191
freeslot = entry;
192+
193+
i = i * 5 + perturb + 1;
194+
j = i & mask;
195+
perturb >>= PERTURB_SHIFT;
196+
197+
entry = &table[j];
198+
if (entry->key == NULL)
199+
break;
244200
}
245-
assert(0); /* NOT REACHED */
246-
return 0;
201+
return freeslot == NULL ? entry : freeslot;
247202
}
248203

249204
/*

0 commit comments

Comments
 (0)