blob: a749f0a33fcc326893db2cb769a270b5a0cbbe1c [file] [log] [blame]
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum4b1302b1993-03-27 18:11:32 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum4b1302b1993-03-27 18:11:32 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum4b1302b1993-03-27 18:11:32 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum4b1302b1993-03-27 18:11:32 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum4b1302b1993-03-27 18:11:32 +000029
30******************************************************************/
31
32/* Mapping object implementation; using a hash table */
33
Guido van Rossum9bfef441993-03-29 10:43:31 +000034/* This file should really be called "dictobject.c", since "mapping"
35 is the generic name for objects with an unorderred arbitrary key
36 set (just like lists are sequences), but since it improves (and was
37 originally derived from) a file by that name I had to change its
38 name. For the user these objects are still called "dictionaries". */
39
Guido van Rossumc0b618a1997-05-02 03:12:38 +000040#include "Python.h"
Guido van Rossum4b1302b1993-03-27 18:11:32 +000041
42
43/*
Guido van Rossum16e93a81997-01-28 00:00:11 +000044 * MINSIZE is the minimum size of a mapping.
45 */
46
47#define MINSIZE 4
48
49/*
50Table of irreducible polynomials to efficiently cycle through
51GF(2^n)-{0}, 2<=n<=30.
Guido van Rossum4b1302b1993-03-27 18:11:32 +000052*/
Guido van Rossum16e93a81997-01-28 00:00:11 +000053static long polys[] = {
Guido van Rossum9e5656c1997-01-29 04:45:16 +000054 4 + 3,
55 8 + 3,
56 16 + 3,
57 32 + 5,
58 64 + 3,
59 128 + 3,
60 256 + 29,
61 512 + 17,
62 1024 + 9,
63 2048 + 5,
64 4096 + 83,
65 8192 + 27,
66 16384 + 43,
67 32768 + 3,
68 65536 + 45,
69 131072 + 9,
70 262144 + 39,
71 524288 + 39,
72 1048576 + 9,
73 2097152 + 5,
74 4194304 + 3,
75 8388608 + 33,
76 16777216 + 27,
77 33554432 + 9,
78 67108864 + 71,
79 134217728 + 39,
80 268435456 + 9,
81 536870912 + 5,
82 1073741824 + 83,
83 0
Guido van Rossum4b1302b1993-03-27 18:11:32 +000084};
85
86/* Object used as dummy key to fill deleted entries */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000087static PyObject *dummy; /* Initialized by first call to newmappingobject() */
Guido van Rossum4b1302b1993-03-27 18:11:32 +000088
89/*
90Invariant for entries: when in use, de_value is not NULL and de_key is
91not NULL and not dummy; when not in use, de_value is NULL and de_key
92is either NULL or dummy. A dummy key value cannot be replaced by
93NULL, since otherwise other keys may be lost.
94*/
95typedef struct {
96 long me_hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000097 PyObject *me_key;
98 PyObject *me_value;
Guido van Rossum36488841997-04-11 19:14:07 +000099#ifdef USE_CACHE_ALIGNED
100 long aligner;
101#endif
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000102} mappingentry;
103
104/*
105To ensure the lookup algorithm terminates, the table size must be a
106prime number and there must be at least one NULL key in the table.
107The value ma_fill is the number of non-NULL keys; ma_used is the number
108of non-NULL, non-dummy keys.
109To avoid slowing down lookups on a near-full table, we resize the table
110when it is more than half filled.
111*/
112typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000113 PyObject_HEAD
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000114 int ma_fill;
115 int ma_used;
116 int ma_size;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000117 int ma_poly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000118 mappingentry *ma_table;
119} mappingobject;
120
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000121PyObject *
122PyDict_New()
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000123{
124 register mappingobject *mp;
125 if (dummy == NULL) { /* Auto-initialize dummy */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000126 dummy = PyString_FromString("<dummy key>");
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000127 if (dummy == NULL)
128 return NULL;
129 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000130 mp = PyObject_NEW(mappingobject, &PyDict_Type);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000131 if (mp == NULL)
132 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000133 mp->ma_size = 0;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000134 mp->ma_poly = 0;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000135 mp->ma_table = NULL;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000136 mp->ma_fill = 0;
137 mp->ma_used = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000138 return (PyObject *)mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000139}
140
141/*
142The basic lookup function used by all operations.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000143This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000144Open addressing is preferred over chaining since the link overhead for
145chaining would be substantial (100% with typical malloc overhead).
Guido van Rossum16e93a81997-01-28 00:00:11 +0000146However, instead of going through the table at constant steps, we cycle
147through the values of GF(2^n)-{0}. This avoids modulo computations, being
148much cheaper on RISC machines, without leading to clustering.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000149
150First a 32-bit hash value, 'sum', is computed from the key string.
151The first character is added an extra time shifted by 8 to avoid hashing
152single-character keys (often heavily used variables) too close together.
153All arithmetic on sum should ignore overflow.
154
155The initial probe index is then computed as sum mod the table size.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000156Subsequent probe indices use the values of x^i in GF(2^n) as an offset,
157where x is a root. The initial value is derived from sum, too.
158
159(This version is due to Reimer Behrends, some ideas are also due to
160Jyrki Alakuijala.)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000161*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000162static mappingentry *lookmapping Py_PROTO((mappingobject *, PyObject *, long));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000163static mappingentry *
164lookmapping(mp, key, hash)
Guido van Rossum7d181591997-01-16 21:06:45 +0000165 mappingobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000166 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000167 long hash;
168{
Guido van Rossum16e93a81997-01-28 00:00:11 +0000169 register int i;
170 register unsigned incr;
171 register unsigned long sum = (unsigned long) hash;
172 register mappingentry *freeslot = NULL;
Guido van Rossum2095d241997-04-09 19:41:24 +0000173 register unsigned int mask = mp->ma_size-1;
Guido van Rossumefb46091997-01-29 15:53:56 +0000174 mappingentry *ep0 = mp->ma_table;
175 register mappingentry *ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000176 /* We must come up with (i, incr) such that 0 <= i < ma_size
177 and 0 < incr < ma_size and both are a function of hash */
178 i = (~sum) & mask;
179 /* We use ~sum instead if sum, as degenerate hash functions, such
180 as for ints <sigh>, can have lots of leading zeros. It's not
181 really a performance risk, but better safe than sorry. */
Guido van Rossumefb46091997-01-29 15:53:56 +0000182 ep = &ep0[i];
Guido van Rossum16e93a81997-01-28 00:00:11 +0000183 if (ep->me_key == NULL)
Guido van Rossum7d181591997-01-16 21:06:45 +0000184 return ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000185 if (ep->me_key == dummy)
Guido van Rossum7d181591997-01-16 21:06:45 +0000186 freeslot = ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000187 else if (ep->me_key == key ||
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000188 (ep->me_hash == hash &&
189 PyObject_Compare(ep->me_key, key) == 0))
190 {
Guido van Rossum16e93a81997-01-28 00:00:11 +0000191 return ep;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000192 }
Guido van Rossumefb46091997-01-29 15:53:56 +0000193 /* Derive incr from sum, just to make it more arbitrary. Note that
Guido van Rossum16e93a81997-01-28 00:00:11 +0000194 incr must not be 0, or we will get into an infinite loop.*/
Guido van Rossumefb46091997-01-29 15:53:56 +0000195 incr = (sum ^ (sum >> 3)) & mask;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000196 if (!incr)
197 incr = mask;
198 if (incr > mask) /* Cycle through GF(2^n)-{0} */
199 incr ^= mp->ma_poly; /* This will implicitly clear the
200 highest bit */
201 for (;;) {
Guido van Rossumefb46091997-01-29 15:53:56 +0000202 ep = &ep0[(i+incr)&mask];
Guido van Rossum16e93a81997-01-28 00:00:11 +0000203 if (ep->me_key == NULL) {
204 if (freeslot != NULL)
205 return freeslot;
206 else
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000207 return ep;
208 }
Guido van Rossum16e93a81997-01-28 00:00:11 +0000209 if (ep->me_key == dummy) {
210 if (freeslot == NULL)
211 freeslot = ep;
212 }
213 else if (ep->me_key == key ||
214 (ep->me_hash == hash &&
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000215 PyObject_Compare(ep->me_key, key) == 0)) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000216 return ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000217 }
218 /* Cycle through GF(2^n)-{0} */
219 incr = incr << 1;
220 if (incr > mask)
221 incr ^= mp->ma_poly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000222 }
223}
224
225/*
226Internal routine to insert a new item into the table.
227Used both by the internal resize routine and by the public insert routine.
228Eats a reference to key and one to value.
229*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000230static void insertmapping
231 Py_PROTO((mappingobject *, PyObject *, long, PyObject *));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000232static void
233insertmapping(mp, key, hash, value)
234 register mappingobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000236 long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 PyObject *value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000238{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000239 PyObject *old_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000240 register mappingentry *ep;
241 ep = lookmapping(mp, key, hash);
242 if (ep->me_value != NULL) {
Guido van Rossumd7047b31995-01-02 19:07:15 +0000243 old_value = ep->me_value;
244 ep->me_value = value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000245 Py_DECREF(old_value); /* which **CAN** re-enter */
246 Py_DECREF(key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000247 }
248 else {
249 if (ep->me_key == NULL)
250 mp->ma_fill++;
251 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000252 Py_DECREF(ep->me_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000253 ep->me_key = key;
254 ep->me_hash = hash;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000255 ep->me_value = value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000256 mp->ma_used++;
257 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000258}
259
260/*
261Restructure the table by allocating a new table and reinserting all
262items again. When entries have been deleted, the new table may
263actually be smaller than the old one.
264*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000265static int mappingresize Py_PROTO((mappingobject *));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000266static int
267mappingresize(mp)
268 mappingobject *mp;
269{
270 register int oldsize = mp->ma_size;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000271 register int newsize, newpoly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000272 register mappingentry *oldtable = mp->ma_table;
273 register mappingentry *newtable;
274 register mappingentry *ep;
275 register int i;
276 newsize = mp->ma_size;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000277 for (i = 0, newsize = MINSIZE; ; i++, newsize <<= 1) {
278 if (i > sizeof(polys)/sizeof(polys[0])) {
279 /* Ran out of polynomials */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000280 PyErr_NoMemory();
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000281 return -1;
282 }
Guido van Rossum16e93a81997-01-28 00:00:11 +0000283 if (newsize > mp->ma_used*2) {
284 newpoly = polys[i];
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000285 break;
286 }
287 }
288 newtable = (mappingentry *) calloc(sizeof(mappingentry), newsize);
289 if (newtable == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000290 PyErr_NoMemory();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000291 return -1;
292 }
293 mp->ma_size = newsize;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000294 mp->ma_poly = newpoly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000295 mp->ma_table = newtable;
296 mp->ma_fill = 0;
297 mp->ma_used = 0;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000298
299 /* Make two passes, so we can avoid decrefs
300 (and possible side effects) till the table is copied */
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000301 for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
302 if (ep->me_value != NULL)
303 insertmapping(mp,ep->me_key,ep->me_hash,ep->me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000304 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000305 for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
306 if (ep->me_value == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000307 Py_XDECREF(ep->me_key);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000308 }
309
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310 PyMem_XDEL(oldtable);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000311 return 0;
312}
313
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000314PyObject *
315PyDict_GetItem(op, key)
316 PyObject *op;
317 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000318{
319 long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000320 if (!PyDict_Check(op)) {
321 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000322 return NULL;
323 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000324 if (((mappingobject *)op)->ma_table == NULL)
325 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000326#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000327 if (!PyString_Check(key) ||
328 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000329#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000330 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000331 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000332 if (hash == -1)
333 return NULL;
334 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000335 return lookmapping((mappingobject *)op, key, hash) -> me_value;
336}
337
338int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000339PyDict_SetItem(op, key, value)
340 register PyObject *op;
341 PyObject *key;
342 PyObject *value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000343{
344 register mappingobject *mp;
345 register long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346 if (!PyDict_Check(op)) {
347 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000348 return -1;
349 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000350 mp = (mappingobject *)op;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000351#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000352 if (PyString_Check(key)) {
Guido van Rossum2a61e741997-01-18 07:55:05 +0000353#ifdef INTERN_STRINGS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000354 if (((PyStringObject *)key)->ob_sinterned != NULL) {
355 key = ((PyStringObject *)key)->ob_sinterned;
356 hash = ((PyStringObject *)key)->ob_shash;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000357 }
358 else
359#endif
360 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000361 hash = ((PyStringObject *)key)->ob_shash;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000362 if (hash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000363 hash = PyObject_Hash(key);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000364 }
365 }
366 else
367#endif
368 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000369 hash = PyObject_Hash(key);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000370 if (hash == -1)
371 return -1;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000372 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000373 /* if fill >= 2/3 size, resize */
374 if (mp->ma_fill*3 >= mp->ma_size*2) {
375 if (mappingresize(mp) != 0) {
376 if (mp->ma_fill+1 > mp->ma_size)
377 return -1;
378 }
379 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 Py_INCREF(value);
381 Py_INCREF(key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000382 insertmapping(mp, key, hash, value);
383 return 0;
384}
385
386int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000387PyDict_DelItem(op, key)
388 PyObject *op;
389 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000390{
391 register mappingobject *mp;
392 register long hash;
393 register mappingentry *ep;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000394 PyObject *old_value, *old_key;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000395
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000396 if (!PyDict_Check(op)) {
397 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000398 return -1;
399 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000400#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000401 if (!PyString_Check(key) ||
402 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000403#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000404 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000405 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000406 if (hash == -1)
407 return -1;
408 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000409 mp = (mappingobject *)op;
Guido van Rossumefc87131995-01-02 19:42:39 +0000410 if (((mappingobject *)op)->ma_table == NULL)
411 goto empty;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000412 ep = lookmapping(mp, key, hash);
413 if (ep->me_value == NULL) {
Guido van Rossumefc87131995-01-02 19:42:39 +0000414 empty:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000415 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000416 return -1;
417 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000418 old_key = ep->me_key;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000419 Py_INCREF(dummy);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000420 ep->me_key = dummy;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000421 old_value = ep->me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000422 ep->me_value = NULL;
423 mp->ma_used--;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000424 Py_DECREF(old_value);
425 Py_DECREF(old_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000426 return 0;
427}
428
Guido van Rossum25831651993-05-19 14:50:45 +0000429void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000430PyDict_Clear(op)
431 PyObject *op;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000432{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000433 int i, n;
434 register mappingentry *table;
435 mappingobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000436 if (!PyDict_Check(op))
Guido van Rossum25831651993-05-19 14:50:45 +0000437 return;
438 mp = (mappingobject *)op;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000439 table = mp->ma_table;
440 if (table == NULL)
441 return;
442 n = mp->ma_size;
443 mp->ma_size = mp->ma_used = mp->ma_fill = 0;
444 mp->ma_table = NULL;
445 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000446 Py_XDECREF(table[i].me_key);
447 Py_XDECREF(table[i].me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000448 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000449 PyMem_DEL(table);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000450}
451
Guido van Rossum25831651993-05-19 14:50:45 +0000452int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000453PyDict_Next(op, ppos, pkey, pvalue)
454 PyObject *op;
Guido van Rossum25831651993-05-19 14:50:45 +0000455 int *ppos;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000456 PyObject **pkey;
457 PyObject **pvalue;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000458{
Guido van Rossum25831651993-05-19 14:50:45 +0000459 int i;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000460 register mappingobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000461 if (!PyDict_Check(op))
Guido van Rossum25831651993-05-19 14:50:45 +0000462 return 0;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000463 mp = (mappingobject *)op;
Guido van Rossum25831651993-05-19 14:50:45 +0000464 i = *ppos;
465 if (i < 0)
466 return 0;
467 while (i < mp->ma_size && mp->ma_table[i].me_value == NULL)
468 i++;
469 *ppos = i+1;
470 if (i >= mp->ma_size)
471 return 0;
472 if (pkey)
473 *pkey = mp->ma_table[i].me_key;
474 if (pvalue)
475 *pvalue = mp->ma_table[i].me_value;
476 return 1;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000477}
478
479/* Methods */
480
481static void
482mapping_dealloc(mp)
483 register mappingobject *mp;
484{
485 register int i;
486 register mappingentry *ep;
487 for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) {
488 if (ep->me_key != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489 Py_DECREF(ep->me_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000490 if (ep->me_value != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000491 Py_DECREF(ep->me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000492 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000493 PyMem_XDEL(mp->ma_table);
494 PyMem_DEL(mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000495}
496
497static int
498mapping_print(mp, fp, flags)
499 register mappingobject *mp;
500 register FILE *fp;
501 register int flags;
502{
503 register int i;
504 register int any;
505 register mappingentry *ep;
506 fprintf(fp, "{");
507 any = 0;
508 for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) {
509 if (ep->me_value != NULL) {
510 if (any++ > 0)
511 fprintf(fp, ", ");
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000512 if (PyObject_Print((PyObject *)ep->me_key, fp, 0) != 0)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000513 return -1;
514 fprintf(fp, ": ");
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000515 if (PyObject_Print(ep->me_value, fp, 0) != 0)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000516 return -1;
517 }
518 }
519 fprintf(fp, "}");
520 return 0;
521}
522
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523static PyObject *
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000524mapping_repr(mp)
525 mappingobject *mp;
526{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000527 auto PyObject *v;
528 PyObject *sepa, *colon;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000529 register int i;
530 register int any;
531 register mappingentry *ep;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000532 v = PyString_FromString("{");
533 sepa = PyString_FromString(", ");
534 colon = PyString_FromString(": ");
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000535 any = 0;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000536 for (i = 0, ep = mp->ma_table; i < mp->ma_size && v; i++, ep++) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000537 if (ep->me_value != NULL) {
538 if (any++)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000539 PyString_Concat(&v, sepa);
540 PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_key));
541 PyString_Concat(&v, colon);
542 PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_value));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000543 }
544 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000545 PyString_ConcatAndDel(&v, PyString_FromString("}"));
546 Py_XDECREF(sepa);
547 Py_XDECREF(colon);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000548 return v;
549}
550
551static int
552mapping_length(mp)
553 mappingobject *mp;
554{
555 return mp->ma_used;
556}
557
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000558static PyObject *
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000559mapping_subscript(mp, key)
560 mappingobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000561 register PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000562{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000563 PyObject *v;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000564 long hash;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000565 if (mp->ma_table == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000566 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000567 return NULL;
568 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000569#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000570 if (!PyString_Check(key) ||
571 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000572#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000573 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000574 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000575 if (hash == -1)
576 return NULL;
577 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000578 v = lookmapping(mp, key, hash) -> me_value;
579 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000580 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000581 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000582 Py_INCREF(v);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000583 return v;
584}
585
586static int
587mapping_ass_sub(mp, v, w)
588 mappingobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000589 PyObject *v, *w;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000590{
591 if (w == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000592 return PyDict_DelItem((PyObject *)mp, v);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000593 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000594 return PyDict_SetItem((PyObject *)mp, v, w);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000595}
596
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000597static PyMappingMethods mapping_as_mapping = {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000598 (inquiry)mapping_length, /*mp_length*/
599 (binaryfunc)mapping_subscript, /*mp_subscript*/
600 (objobjargproc)mapping_ass_sub, /*mp_ass_subscript*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000601};
602
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000603static PyObject *
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000604mapping_keys(mp, args)
605 register mappingobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000606 PyObject *args;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000607{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000608 register PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000609 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000610 if (!PyArg_NoArgs(args))
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000611 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000612 v = PyList_New(mp->ma_used);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000613 if (v == NULL)
614 return NULL;
615 for (i = 0, j = 0; i < mp->ma_size; i++) {
616 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000617 PyObject *key = mp->ma_table[i].me_key;
618 Py_INCREF(key);
619 PyList_SetItem(v, j, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000620 j++;
621 }
622 }
623 return v;
624}
625
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000626static PyObject *
Guido van Rossum25831651993-05-19 14:50:45 +0000627mapping_values(mp, args)
628 register mappingobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000629 PyObject *args;
Guido van Rossum25831651993-05-19 14:50:45 +0000630{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000631 register PyObject *v;
Guido van Rossum25831651993-05-19 14:50:45 +0000632 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000633 if (!PyArg_NoArgs(args))
Guido van Rossum25831651993-05-19 14:50:45 +0000634 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000635 v = PyList_New(mp->ma_used);
Guido van Rossum25831651993-05-19 14:50:45 +0000636 if (v == NULL)
637 return NULL;
638 for (i = 0, j = 0; i < mp->ma_size; i++) {
639 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000640 PyObject *value = mp->ma_table[i].me_value;
641 Py_INCREF(value);
642 PyList_SetItem(v, j, value);
Guido van Rossum25831651993-05-19 14:50:45 +0000643 j++;
644 }
645 }
646 return v;
647}
648
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000649static PyObject *
Guido van Rossum25831651993-05-19 14:50:45 +0000650mapping_items(mp, args)
651 register mappingobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000652 PyObject *args;
Guido van Rossum25831651993-05-19 14:50:45 +0000653{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654 register PyObject *v;
Guido van Rossum25831651993-05-19 14:50:45 +0000655 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000656 if (!PyArg_NoArgs(args))
Guido van Rossum25831651993-05-19 14:50:45 +0000657 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000658 v = PyList_New(mp->ma_used);
Guido van Rossum25831651993-05-19 14:50:45 +0000659 if (v == NULL)
660 return NULL;
661 for (i = 0, j = 0; i < mp->ma_size; i++) {
662 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000663 PyObject *key = mp->ma_table[i].me_key;
664 PyObject *value = mp->ma_table[i].me_value;
665 PyObject *item = PyTuple_New(2);
Guido van Rossum25831651993-05-19 14:50:45 +0000666 if (item == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000667 Py_DECREF(v);
Guido van Rossum25831651993-05-19 14:50:45 +0000668 return NULL;
669 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000670 Py_INCREF(key);
671 PyTuple_SetItem(item, 0, key);
672 Py_INCREF(value);
673 PyTuple_SetItem(item, 1, value);
674 PyList_SetItem(v, j, item);
Guido van Rossum25831651993-05-19 14:50:45 +0000675 j++;
676 }
677 }
678 return v;
679}
680
Guido van Rossum4199fac1993-11-05 10:18:44 +0000681int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000682PyDict_Size(mp)
683 PyObject *mp;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000684{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000685 if (mp == NULL || !PyDict_Check(mp)) {
686 PyErr_BadInternalCall();
Guido van Rossumb376a4a1993-11-23 17:53:17 +0000687 return 0;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000688 }
689 return ((mappingobject *)mp)->ma_used;
690}
691
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000692PyObject *
693PyDict_Keys(mp)
694 PyObject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000695{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000696 if (mp == NULL || !PyDict_Check(mp)) {
697 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000698 return NULL;
699 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000700 return mapping_keys((mappingobject *)mp, (PyObject *)NULL);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000701}
702
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000703PyObject *
704PyDict_Values(mp)
705 PyObject *mp;
Guido van Rossum25831651993-05-19 14:50:45 +0000706{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000707 if (mp == NULL || !PyDict_Check(mp)) {
708 PyErr_BadInternalCall();
Guido van Rossum25831651993-05-19 14:50:45 +0000709 return NULL;
710 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000711 return mapping_values((mappingobject *)mp, (PyObject *)NULL);
Guido van Rossum25831651993-05-19 14:50:45 +0000712}
713
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000714PyObject *
715PyDict_Items(mp)
716 PyObject *mp;
Guido van Rossum25831651993-05-19 14:50:45 +0000717{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000718 if (mp == NULL || !PyDict_Check(mp)) {
719 PyErr_BadInternalCall();
Guido van Rossum25831651993-05-19 14:50:45 +0000720 return NULL;
721 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000722 return mapping_items((mappingobject *)mp, (PyObject *)NULL);
Guido van Rossum25831651993-05-19 14:50:45 +0000723}
724
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000725#define NEWCMP
726
727#ifdef NEWCMP
728
729/* Subroutine which returns the smallest key in a for which b's value
730 is different or absent. The value is returned too, through the
731 pval argument. No reference counts are incremented. */
732
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000733static PyObject *
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000734characterize(a, b, pval)
735 mappingobject *a;
736 mappingobject *b;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000737 PyObject **pval;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000738{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000739 PyObject *diff = NULL;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000740 int i;
741
742 *pval = NULL;
743 for (i = 0; i < a->ma_size; i++) {
744 if (a->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000745 PyObject *key = a->ma_table[i].me_key;
746 PyObject *aval, *bval;
747 if (diff != NULL && PyObject_Compare(key, diff) > 0)
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000748 continue;
749 aval = a->ma_table[i].me_value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000750 bval = PyDict_GetItem((PyObject *)b, key);
751 if (bval == NULL || PyObject_Compare(aval, bval) != 0)
752 {
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000753 diff = key;
754 *pval = aval;
755 }
756 }
757 }
758 return diff;
759}
760
761static int
762mapping_compare(a, b)
763 mappingobject *a, *b;
764{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000765 PyObject *adiff, *bdiff, *aval, *bval;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000766 int res;
767
768 /* Compare lengths first */
769 if (a->ma_used < b->ma_used)
770 return -1; /* a is shorter */
771 else if (a->ma_used > b->ma_used)
772 return 1; /* b is shorter */
773 /* Same length -- check all keys */
774 adiff = characterize(a, b, &aval);
775 if (adiff == NULL)
776 return 0; /* a is a subset with the same length */
777 bdiff = characterize(b, a, &bval);
778 /* bdiff == NULL would be impossible now */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000779 res = PyObject_Compare(adiff, bdiff);
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000780 if (res == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000781 res = PyObject_Compare(aval, bval);
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000782 return res;
783}
784
785#else /* !NEWCMP */
786
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000787static int
788mapping_compare(a, b)
789 mappingobject *a, *b;
790{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000791 PyObject *akeys, *bkeys;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000792 int i, n, res;
793 if (a == b)
794 return 0;
795 if (a->ma_used == 0) {
796 if (b->ma_used != 0)
797 return -1;
798 else
799 return 0;
800 }
801 else {
802 if (b->ma_used == 0)
803 return 1;
804 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000805 akeys = mapping_keys(a, (PyObject *)NULL);
806 bkeys = mapping_keys(b, (PyObject *)NULL);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000807 if (akeys == NULL || bkeys == NULL) {
808 /* Oops, out of memory -- what to do? */
809 /* For now, sort on address! */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000810 Py_XDECREF(akeys);
811 Py_XDECREF(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000812 if (a < b)
813 return -1;
814 else
815 return 1;
816 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000817 PyList_Sort(akeys);
818 PyList_Sort(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000819 n = a->ma_used < b->ma_used ? a->ma_used : b->ma_used; /* smallest */
820 res = 0;
821 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000822 PyObject *akey, *bkey, *aval, *bval;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000823 long ahash, bhash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000824 akey = PyList_GetItem(akeys, i);
825 bkey = PyList_GetItem(bkeys, i);
826 res = PyObject_Compare(akey, bkey);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000827 if (res != 0)
828 break;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000829#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000830 if (!PyString_Check(akey) ||
831 (ahash = ((PyStringObject *) akey)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000832#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000833 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000834 ahash = PyObject_Hash(akey);
Guido van Rossumca756f21997-01-23 19:39:29 +0000835 if (ahash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000836 PyErr_Clear(); /* Don't want errors here */
Guido van Rossumca756f21997-01-23 19:39:29 +0000837 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000838#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000839 if (!PyString_Check(bkey) ||
840 (bhash = ((PyStringObject *) bkey)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000841#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000842 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000843 bhash = PyObject_Hash(bkey);
Guido van Rossumca756f21997-01-23 19:39:29 +0000844 if (bhash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000845 PyErr_Clear(); /* Don't want errors here */
Guido van Rossumca756f21997-01-23 19:39:29 +0000846 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000847 aval = lookmapping(a, akey, ahash) -> me_value;
848 bval = lookmapping(b, bkey, bhash) -> me_value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000849 res = PyObject_Compare(aval, bval);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000850 if (res != 0)
851 break;
852 }
853 if (res == 0) {
854 if (a->ma_used < b->ma_used)
855 res = -1;
856 else if (a->ma_used > b->ma_used)
857 res = 1;
858 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000859 Py_DECREF(akeys);
860 Py_DECREF(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000861 return res;
862}
863
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000864#endif /* !NEWCMP */
865
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000866static PyObject *
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000867mapping_has_key(mp, args)
868 register mappingobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000869 PyObject *args;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000870{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000871 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000872 long hash;
873 register long ok;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000874 if (!PyArg_Parse(args, "O", &key))
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000875 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000876#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000877 if (!PyString_Check(key) ||
878 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000879#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000880 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000881 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000882 if (hash == -1)
883 return NULL;
884 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000885 ok = mp->ma_size != 0 && lookmapping(mp, key, hash)->me_value != NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000886 return PyInt_FromLong(ok);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000887}
888
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000889static PyObject *
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000890mapping_clear(mp, args)
891 register mappingobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000892 PyObject *args;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000893{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000894 if (!PyArg_NoArgs(args))
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000895 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000896 PyDict_Clear((PyObject *)mp);
897 Py_INCREF(Py_None);
898 return Py_None;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000899}
900
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000901static PyMethodDef mapp_methods[] = {
902 {"clear", (PyCFunction)mapping_clear},
903 {"has_key", (PyCFunction)mapping_has_key},
904 {"items", (PyCFunction)mapping_items},
905 {"keys", (PyCFunction)mapping_keys},
906 {"values", (PyCFunction)mapping_values},
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000907 {NULL, NULL} /* sentinel */
908};
909
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000910static PyObject *
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000911mapping_getattr(mp, name)
912 mappingobject *mp;
913 char *name;
914{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000915 return Py_FindMethod(mapp_methods, (PyObject *)mp, name);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000916}
917
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000918PyTypeObject PyDict_Type = {
919 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000920 0,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000921 "dictionary",
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000922 sizeof(mappingobject),
923 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000924 (destructor)mapping_dealloc, /*tp_dealloc*/
925 (printfunc)mapping_print, /*tp_print*/
926 (getattrfunc)mapping_getattr, /*tp_getattr*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000927 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000928 (cmpfunc)mapping_compare, /*tp_compare*/
929 (reprfunc)mapping_repr, /*tp_repr*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000930 0, /*tp_as_number*/
931 0, /*tp_as_sequence*/
932 &mapping_as_mapping, /*tp_as_mapping*/
933};
934
935/* For backward compatibility with old dictionary interface */
936
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000937static PyObject *last_name_object;
Guido van Rossum992ded81995-12-08 01:16:31 +0000938static char *last_name_char; /* NULL or == getstringvalue(last_name_object) */
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000939
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000940PyObject *
941PyObject_GetAttr(v, name)
942 PyObject *v;
943 PyObject *name;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000944{
Guido van Rossumd8eb1b31996-08-09 20:52:03 +0000945 if (v->ob_type->tp_getattro != NULL)
946 return (*v->ob_type->tp_getattro)(v, name);
947
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000948 if (name != last_name_object) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000949 Py_XDECREF(last_name_object);
950 Py_INCREF(name);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000951 last_name_object = name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000952 last_name_char = PyString_AsString(name);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000953 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000954 return PyObject_GetAttrString(v, last_name_char);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000955}
956
957int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000958PyObject_SetAttr(v, name, value)
959 PyObject *v;
960 PyObject *name;
961 PyObject *value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000962{
Guido van Rossum2a61e741997-01-18 07:55:05 +0000963 int err;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000964 Py_INCREF(name);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000965 PyString_InternInPlace(&name);
Guido van Rossumd8eb1b31996-08-09 20:52:03 +0000966 if (v->ob_type->tp_setattro != NULL)
Guido van Rossum2a61e741997-01-18 07:55:05 +0000967 err = (*v->ob_type->tp_setattro)(v, name, value);
968 else {
969 if (name != last_name_object) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000970 Py_XDECREF(last_name_object);
971 Py_INCREF(name);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000972 last_name_object = name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000973 last_name_char = PyString_AsString(name);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000974 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000975 err = PyObject_SetAttrString(v, last_name_char, value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000976 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000977 Py_DECREF(name);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000978 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000979}
980
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000981PyObject *
982PyDict_GetItemString(v, key)
983 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000984 char *key;
985{
Guido van Rossum992ded81995-12-08 01:16:31 +0000986 if (key != last_name_char) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000987 Py_XDECREF(last_name_object);
988 last_name_object = PyString_FromString(key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000989 if (last_name_object == NULL) {
990 last_name_char = NULL;
991 return NULL;
992 }
Guido van Rossum2a61e741997-01-18 07:55:05 +0000993 PyString_InternInPlace(&last_name_object);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000994 last_name_char = PyString_AsString(last_name_object);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000995 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000996 return PyDict_GetItem(v, last_name_object);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000997}
998
999int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001000PyDict_SetItemString(v, key, item)
1001 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001002 char *key;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001003 PyObject *item;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001004{
Guido van Rossum992ded81995-12-08 01:16:31 +00001005 if (key != last_name_char) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001006 Py_XDECREF(last_name_object);
1007 last_name_object = PyString_FromString(key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001008 if (last_name_object == NULL) {
1009 last_name_char = NULL;
Guido van Rossum1fc238a1993-07-29 08:25:09 +00001010 return -1;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001011 }
Guido van Rossum2a61e741997-01-18 07:55:05 +00001012 PyString_InternInPlace(&last_name_object);
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001013 last_name_char = PyString_AsString(last_name_object);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001014 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001015 return PyDict_SetItem(v, last_name_object, item);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001016}
1017
1018int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001019PyDict_DelItemString(v, key)
1020 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001021 char *key;
1022{
Guido van Rossum992ded81995-12-08 01:16:31 +00001023 if (key != last_name_char) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001024 Py_XDECREF(last_name_object);
1025 last_name_object = PyString_FromString(key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001026 if (last_name_object == NULL) {
1027 last_name_char = NULL;
Guido van Rossum1fc238a1993-07-29 08:25:09 +00001028 return -1;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001029 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001030 last_name_char = PyString_AsString(last_name_object);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001031 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001032 return PyDict_DelItem(v, last_name_object);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001033}