blob: 6f92f67bed310f31924bab5f641c404a415dcf43 [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
Guido van Rossuma9e7a811997-05-13 21:02:11 +000032/* Dictionaru object implementation using a hash table */
Guido van Rossum9bfef441993-03-29 10:43:31 +000033
Guido van Rossumc0b618a1997-05-02 03:12:38 +000034#include "Python.h"
Guido van Rossum4b1302b1993-03-27 18:11:32 +000035
36
37/*
Guido van Rossuma9e7a811997-05-13 21:02:11 +000038 * MINSIZE is the minimum size of a dictionary.
Guido van Rossum16e93a81997-01-28 00:00:11 +000039 */
40
41#define MINSIZE 4
42
43/*
44Table of irreducible polynomials to efficiently cycle through
45GF(2^n)-{0}, 2<=n<=30.
Guido van Rossum4b1302b1993-03-27 18:11:32 +000046*/
Guido van Rossum16e93a81997-01-28 00:00:11 +000047static long polys[] = {
Guido van Rossum9e5656c1997-01-29 04:45:16 +000048 4 + 3,
49 8 + 3,
50 16 + 3,
51 32 + 5,
52 64 + 3,
53 128 + 3,
54 256 + 29,
55 512 + 17,
56 1024 + 9,
57 2048 + 5,
58 4096 + 83,
59 8192 + 27,
60 16384 + 43,
61 32768 + 3,
62 65536 + 45,
63 131072 + 9,
64 262144 + 39,
65 524288 + 39,
66 1048576 + 9,
67 2097152 + 5,
68 4194304 + 3,
69 8388608 + 33,
70 16777216 + 27,
71 33554432 + 9,
72 67108864 + 71,
73 134217728 + 39,
74 268435456 + 9,
75 536870912 + 5,
76 1073741824 + 83,
77 0
Guido van Rossum4b1302b1993-03-27 18:11:32 +000078};
79
80/* Object used as dummy key to fill deleted entries */
Guido van Rossuma9e7a811997-05-13 21:02:11 +000081static PyObject *dummy; /* Initialized by first call to newdictobject() */
Guido van Rossum4b1302b1993-03-27 18:11:32 +000082
83/*
84Invariant for entries: when in use, de_value is not NULL and de_key is
85not NULL and not dummy; when not in use, de_value is NULL and de_key
86is either NULL or dummy. A dummy key value cannot be replaced by
87NULL, since otherwise other keys may be lost.
88*/
89typedef struct {
90 long me_hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091 PyObject *me_key;
92 PyObject *me_value;
Guido van Rossum36488841997-04-11 19:14:07 +000093#ifdef USE_CACHE_ALIGNED
94 long aligner;
95#endif
Guido van Rossuma9e7a811997-05-13 21:02:11 +000096} dictentry;
Guido van Rossum4b1302b1993-03-27 18:11:32 +000097
98/*
99To ensure the lookup algorithm terminates, the table size must be a
100prime number and there must be at least one NULL key in the table.
101The value ma_fill is the number of non-NULL keys; ma_used is the number
102of non-NULL, non-dummy keys.
103To avoid slowing down lookups on a near-full table, we resize the table
104when it is more than half filled.
105*/
106typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000107 PyObject_HEAD
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000108 int ma_fill;
109 int ma_used;
110 int ma_size;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000111 int ma_poly;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000112 dictentry *ma_table;
113} dictobject;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000114
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000115PyObject *
116PyDict_New()
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000117{
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000118 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000119 if (dummy == NULL) { /* Auto-initialize dummy */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000120 dummy = PyString_FromString("<dummy key>");
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000121 if (dummy == NULL)
122 return NULL;
123 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000124 mp = PyObject_NEW(dictobject, &PyDict_Type);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000125 if (mp == NULL)
126 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000127 mp->ma_size = 0;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000128 mp->ma_poly = 0;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000129 mp->ma_table = NULL;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000130 mp->ma_fill = 0;
131 mp->ma_used = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000132 return (PyObject *)mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000133}
134
135/*
136The basic lookup function used by all operations.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000137This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000138Open addressing is preferred over chaining since the link overhead for
139chaining would be substantial (100% with typical malloc overhead).
Guido van Rossum16e93a81997-01-28 00:00:11 +0000140However, instead of going through the table at constant steps, we cycle
141through the values of GF(2^n)-{0}. This avoids modulo computations, being
142much cheaper on RISC machines, without leading to clustering.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000143
144First a 32-bit hash value, 'sum', is computed from the key string.
145The first character is added an extra time shifted by 8 to avoid hashing
146single-character keys (often heavily used variables) too close together.
147All arithmetic on sum should ignore overflow.
148
149The initial probe index is then computed as sum mod the table size.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000150Subsequent probe indices use the values of x^i in GF(2^n) as an offset,
151where x is a root. The initial value is derived from sum, too.
152
153(This version is due to Reimer Behrends, some ideas are also due to
154Jyrki Alakuijala.)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000155*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000156static dictentry *lookdict Py_PROTO((dictobject *, PyObject *, long));
157static dictentry *
158lookdict(mp, key, hash)
159 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000160 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000161 long hash;
162{
Guido van Rossum16e93a81997-01-28 00:00:11 +0000163 register int i;
164 register unsigned incr;
165 register unsigned long sum = (unsigned long) hash;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000166 register dictentry *freeslot = NULL;
Guido van Rossum2095d241997-04-09 19:41:24 +0000167 register unsigned int mask = mp->ma_size-1;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000168 dictentry *ep0 = mp->ma_table;
169 register dictentry *ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000170 /* We must come up with (i, incr) such that 0 <= i < ma_size
171 and 0 < incr < ma_size and both are a function of hash */
172 i = (~sum) & mask;
173 /* We use ~sum instead if sum, as degenerate hash functions, such
174 as for ints <sigh>, can have lots of leading zeros. It's not
175 really a performance risk, but better safe than sorry. */
Guido van Rossumefb46091997-01-29 15:53:56 +0000176 ep = &ep0[i];
Guido van Rossum16e93a81997-01-28 00:00:11 +0000177 if (ep->me_key == NULL)
Guido van Rossum7d181591997-01-16 21:06:45 +0000178 return ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000179 if (ep->me_key == dummy)
Guido van Rossum7d181591997-01-16 21:06:45 +0000180 freeslot = ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000181 else if (ep->me_key == key ||
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000182 (ep->me_hash == hash &&
183 PyObject_Compare(ep->me_key, key) == 0))
184 {
Guido van Rossum16e93a81997-01-28 00:00:11 +0000185 return ep;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000186 }
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000187 /* XXX What if PyObject_Compare returned an exception? */
Guido van Rossumefb46091997-01-29 15:53:56 +0000188 /* Derive incr from sum, just to make it more arbitrary. Note that
Guido van Rossum16e93a81997-01-28 00:00:11 +0000189 incr must not be 0, or we will get into an infinite loop.*/
Guido van Rossumefb46091997-01-29 15:53:56 +0000190 incr = (sum ^ (sum >> 3)) & mask;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000191 if (!incr)
192 incr = mask;
193 if (incr > mask) /* Cycle through GF(2^n)-{0} */
194 incr ^= mp->ma_poly; /* This will implicitly clear the
195 highest bit */
196 for (;;) {
Guido van Rossumefb46091997-01-29 15:53:56 +0000197 ep = &ep0[(i+incr)&mask];
Guido van Rossum16e93a81997-01-28 00:00:11 +0000198 if (ep->me_key == NULL) {
199 if (freeslot != NULL)
200 return freeslot;
201 else
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000202 return ep;
203 }
Guido van Rossum16e93a81997-01-28 00:00:11 +0000204 if (ep->me_key == dummy) {
205 if (freeslot == NULL)
206 freeslot = ep;
207 }
208 else if (ep->me_key == key ||
209 (ep->me_hash == hash &&
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000210 PyObject_Compare(ep->me_key, key) == 0)) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000211 return ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000212 }
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000213 /* XXX What if PyObject_Compare returned an exception? */
Guido van Rossum16e93a81997-01-28 00:00:11 +0000214 /* Cycle through GF(2^n)-{0} */
215 incr = incr << 1;
216 if (incr > mask)
217 incr ^= mp->ma_poly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000218 }
219}
220
221/*
222Internal routine to insert a new item into the table.
223Used both by the internal resize routine and by the public insert routine.
224Eats a reference to key and one to value.
225*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000226static void insertdict
227 Py_PROTO((dictobject *, PyObject *, long, PyObject *));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000228static void
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000229insertdict(mp, key, hash, value)
230 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000232 long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 PyObject *value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000234{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235 PyObject *old_value;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000236 register dictentry *ep;
237 ep = lookdict(mp, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000238 if (ep->me_value != NULL) {
Guido van Rossumd7047b31995-01-02 19:07:15 +0000239 old_value = ep->me_value;
240 ep->me_value = value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000241 Py_DECREF(old_value); /* which **CAN** re-enter */
242 Py_DECREF(key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000243 }
244 else {
245 if (ep->me_key == NULL)
246 mp->ma_fill++;
247 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000248 Py_DECREF(ep->me_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000249 ep->me_key = key;
250 ep->me_hash = hash;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000251 ep->me_value = value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000252 mp->ma_used++;
253 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000254}
255
256/*
257Restructure the table by allocating a new table and reinserting all
258items again. When entries have been deleted, the new table may
259actually be smaller than the old one.
260*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000261static int dictresize Py_PROTO((dictobject *));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000262static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000263dictresize(mp)
264 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000265{
266 register int oldsize = mp->ma_size;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000267 register int newsize, newpoly;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000268 register dictentry *oldtable = mp->ma_table;
269 register dictentry *newtable;
270 register dictentry *ep;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000271 register int i;
272 newsize = mp->ma_size;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000273 for (i = 0, newsize = MINSIZE; ; i++, newsize <<= 1) {
274 if (i > sizeof(polys)/sizeof(polys[0])) {
275 /* Ran out of polynomials */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000276 PyErr_NoMemory();
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000277 return -1;
278 }
Guido van Rossum16e93a81997-01-28 00:00:11 +0000279 if (newsize > mp->ma_used*2) {
280 newpoly = polys[i];
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000281 break;
282 }
283 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000284 newtable = (dictentry *) calloc(sizeof(dictentry), newsize);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000285 if (newtable == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000286 PyErr_NoMemory();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000287 return -1;
288 }
289 mp->ma_size = newsize;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000290 mp->ma_poly = newpoly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000291 mp->ma_table = newtable;
292 mp->ma_fill = 0;
293 mp->ma_used = 0;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000294
295 /* Make two passes, so we can avoid decrefs
296 (and possible side effects) till the table is copied */
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000297 for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
298 if (ep->me_value != NULL)
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000299 insertdict(mp,ep->me_key,ep->me_hash,ep->me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000300 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000301 for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
302 if (ep->me_value == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000303 Py_XDECREF(ep->me_key);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000304 }
305
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306 PyMem_XDEL(oldtable);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000307 return 0;
308}
309
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310PyObject *
311PyDict_GetItem(op, key)
312 PyObject *op;
313 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000314{
315 long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000316 if (!PyDict_Check(op)) {
317 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000318 return NULL;
319 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000320 if (((dictobject *)op)->ma_table == NULL)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000321 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000322#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000323 if (!PyString_Check(key) ||
324 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000325#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000326 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000327 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000328 if (hash == -1)
329 return NULL;
330 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000331 return lookdict((dictobject *)op, key, hash) -> me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000332}
333
334int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000335PyDict_SetItem(op, key, value)
336 register PyObject *op;
337 PyObject *key;
338 PyObject *value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000339{
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000340 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000341 register long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000342 if (!PyDict_Check(op)) {
343 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000344 return -1;
345 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000346 mp = (dictobject *)op;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000347#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000348 if (PyString_Check(key)) {
Guido van Rossum2a61e741997-01-18 07:55:05 +0000349#ifdef INTERN_STRINGS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000350 if (((PyStringObject *)key)->ob_sinterned != NULL) {
351 key = ((PyStringObject *)key)->ob_sinterned;
352 hash = ((PyStringObject *)key)->ob_shash;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000353 }
354 else
355#endif
356 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000357 hash = ((PyStringObject *)key)->ob_shash;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000358 if (hash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000359 hash = PyObject_Hash(key);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000360 }
361 }
362 else
363#endif
364 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000365 hash = PyObject_Hash(key);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000366 if (hash == -1)
367 return -1;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000368 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000369 /* if fill >= 2/3 size, resize */
370 if (mp->ma_fill*3 >= mp->ma_size*2) {
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000371 if (dictresize(mp) != 0) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000372 if (mp->ma_fill+1 > mp->ma_size)
373 return -1;
374 }
375 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000376 Py_INCREF(value);
377 Py_INCREF(key);
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000378 insertdict(mp, key, hash, value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000379 return 0;
380}
381
382int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000383PyDict_DelItem(op, key)
384 PyObject *op;
385 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000386{
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000387 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000388 register long hash;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000389 register dictentry *ep;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390 PyObject *old_value, *old_key;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000391
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 if (!PyDict_Check(op)) {
393 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000394 return -1;
395 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000396#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000397 if (!PyString_Check(key) ||
398 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000399#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000400 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000401 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000402 if (hash == -1)
403 return -1;
404 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000405 mp = (dictobject *)op;
406 if (((dictobject *)op)->ma_table == NULL)
Guido van Rossumefc87131995-01-02 19:42:39 +0000407 goto empty;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000408 ep = lookdict(mp, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000409 if (ep->me_value == NULL) {
Guido van Rossumefc87131995-01-02 19:42:39 +0000410 empty:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000411 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000412 return -1;
413 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000414 old_key = ep->me_key;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000415 Py_INCREF(dummy);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000416 ep->me_key = dummy;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000417 old_value = ep->me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000418 ep->me_value = NULL;
419 mp->ma_used--;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000420 Py_DECREF(old_value);
421 Py_DECREF(old_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000422 return 0;
423}
424
Guido van Rossum25831651993-05-19 14:50:45 +0000425void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000426PyDict_Clear(op)
427 PyObject *op;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000428{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000429 int i, n;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000430 register dictentry *table;
431 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432 if (!PyDict_Check(op))
Guido van Rossum25831651993-05-19 14:50:45 +0000433 return;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000434 mp = (dictobject *)op;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000435 table = mp->ma_table;
436 if (table == NULL)
437 return;
438 n = mp->ma_size;
439 mp->ma_size = mp->ma_used = mp->ma_fill = 0;
440 mp->ma_table = NULL;
441 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000442 Py_XDECREF(table[i].me_key);
443 Py_XDECREF(table[i].me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000444 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000445 PyMem_DEL(table);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000446}
447
Guido van Rossum25831651993-05-19 14:50:45 +0000448int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000449PyDict_Next(op, ppos, pkey, pvalue)
450 PyObject *op;
Guido van Rossum25831651993-05-19 14:50:45 +0000451 int *ppos;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000452 PyObject **pkey;
453 PyObject **pvalue;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000454{
Guido van Rossum25831651993-05-19 14:50:45 +0000455 int i;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000456 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000457 if (!PyDict_Check(op))
Guido van Rossum25831651993-05-19 14:50:45 +0000458 return 0;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000459 mp = (dictobject *)op;
Guido van Rossum25831651993-05-19 14:50:45 +0000460 i = *ppos;
461 if (i < 0)
462 return 0;
463 while (i < mp->ma_size && mp->ma_table[i].me_value == NULL)
464 i++;
465 *ppos = i+1;
466 if (i >= mp->ma_size)
467 return 0;
468 if (pkey)
469 *pkey = mp->ma_table[i].me_key;
470 if (pvalue)
471 *pvalue = mp->ma_table[i].me_value;
472 return 1;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000473}
474
475/* Methods */
476
477static void
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000478dict_dealloc(mp)
479 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000480{
481 register int i;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000482 register dictentry *ep;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000483 for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) {
484 if (ep->me_key != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000485 Py_DECREF(ep->me_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000486 if (ep->me_value != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000487 Py_DECREF(ep->me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000488 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489 PyMem_XDEL(mp->ma_table);
490 PyMem_DEL(mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000491}
492
493static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000494dict_print(mp, fp, flags)
495 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000496 register FILE *fp;
497 register int flags;
498{
499 register int i;
500 register int any;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000501 register dictentry *ep;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000502 fprintf(fp, "{");
503 any = 0;
504 for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) {
505 if (ep->me_value != NULL) {
506 if (any++ > 0)
507 fprintf(fp, ", ");
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000508 if (PyObject_Print((PyObject *)ep->me_key, fp, 0) != 0)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000509 return -1;
510 fprintf(fp, ": ");
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000511 if (PyObject_Print(ep->me_value, fp, 0) != 0)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000512 return -1;
513 }
514 }
515 fprintf(fp, "}");
516 return 0;
517}
518
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000519static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000520dict_repr(mp)
521 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000522{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523 auto PyObject *v;
524 PyObject *sepa, *colon;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000525 register int i;
526 register int any;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000527 register dictentry *ep;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000528 v = PyString_FromString("{");
529 sepa = PyString_FromString(", ");
530 colon = PyString_FromString(": ");
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000531 any = 0;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000532 for (i = 0, ep = mp->ma_table; i < mp->ma_size && v; i++, ep++) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000533 if (ep->me_value != NULL) {
534 if (any++)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000535 PyString_Concat(&v, sepa);
536 PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_key));
537 PyString_Concat(&v, colon);
538 PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_value));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000539 }
540 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000541 PyString_ConcatAndDel(&v, PyString_FromString("}"));
542 Py_XDECREF(sepa);
543 Py_XDECREF(colon);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000544 return v;
545}
546
547static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000548dict_length(mp)
549 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000550{
551 return mp->ma_used;
552}
553
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000554static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000555dict_subscript(mp, key)
556 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000557 register PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000558{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559 PyObject *v;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000560 long hash;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000561 if (mp->ma_table == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000562 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000563 return NULL;
564 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000565#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000566 if (!PyString_Check(key) ||
567 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000568#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000569 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000570 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000571 if (hash == -1)
572 return NULL;
573 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000574 v = lookdict(mp, key, hash) -> me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000575 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000576 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000577 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000578 Py_INCREF(v);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000579 return v;
580}
581
582static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000583dict_ass_sub(mp, v, w)
584 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000585 PyObject *v, *w;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000586{
587 if (w == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000588 return PyDict_DelItem((PyObject *)mp, v);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000589 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000590 return PyDict_SetItem((PyObject *)mp, v, w);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000591}
592
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000593static PyMappingMethods dict_as_mapping = {
594 (inquiry)dict_length, /*mp_length*/
595 (binaryfunc)dict_subscript, /*mp_subscript*/
596 (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000597};
598
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000599static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000600dict_keys(mp, args)
601 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000602 PyObject *args;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000603{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604 register PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000605 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000606 if (!PyArg_NoArgs(args))
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000607 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000608 v = PyList_New(mp->ma_used);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000609 if (v == NULL)
610 return NULL;
611 for (i = 0, j = 0; i < mp->ma_size; i++) {
612 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000613 PyObject *key = mp->ma_table[i].me_key;
614 Py_INCREF(key);
615 PyList_SetItem(v, j, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000616 j++;
617 }
618 }
619 return v;
620}
621
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000622static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000623dict_values(mp, args)
624 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 PyObject *args;
Guido van Rossum25831651993-05-19 14:50:45 +0000626{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 register PyObject *v;
Guido van Rossum25831651993-05-19 14:50:45 +0000628 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000629 if (!PyArg_NoArgs(args))
Guido van Rossum25831651993-05-19 14:50:45 +0000630 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000631 v = PyList_New(mp->ma_used);
Guido van Rossum25831651993-05-19 14:50:45 +0000632 if (v == NULL)
633 return NULL;
634 for (i = 0, j = 0; i < mp->ma_size; i++) {
635 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000636 PyObject *value = mp->ma_table[i].me_value;
637 Py_INCREF(value);
638 PyList_SetItem(v, j, value);
Guido van Rossum25831651993-05-19 14:50:45 +0000639 j++;
640 }
641 }
642 return v;
643}
644
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000645static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000646dict_items(mp, args)
647 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000648 PyObject *args;
Guido van Rossum25831651993-05-19 14:50:45 +0000649{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000650 register PyObject *v;
Guido van Rossum25831651993-05-19 14:50:45 +0000651 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000652 if (!PyArg_NoArgs(args))
Guido van Rossum25831651993-05-19 14:50:45 +0000653 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654 v = PyList_New(mp->ma_used);
Guido van Rossum25831651993-05-19 14:50:45 +0000655 if (v == NULL)
656 return NULL;
657 for (i = 0, j = 0; i < mp->ma_size; i++) {
658 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000659 PyObject *key = mp->ma_table[i].me_key;
660 PyObject *value = mp->ma_table[i].me_value;
661 PyObject *item = PyTuple_New(2);
Guido van Rossum25831651993-05-19 14:50:45 +0000662 if (item == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000663 Py_DECREF(v);
Guido van Rossum25831651993-05-19 14:50:45 +0000664 return NULL;
665 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000666 Py_INCREF(key);
667 PyTuple_SetItem(item, 0, key);
668 Py_INCREF(value);
669 PyTuple_SetItem(item, 1, value);
670 PyList_SetItem(v, j, item);
Guido van Rossum25831651993-05-19 14:50:45 +0000671 j++;
672 }
673 }
674 return v;
675}
676
Guido van Rossum4199fac1993-11-05 10:18:44 +0000677int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000678PyDict_Size(mp)
679 PyObject *mp;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000680{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000681 if (mp == NULL || !PyDict_Check(mp)) {
682 PyErr_BadInternalCall();
Guido van Rossumb376a4a1993-11-23 17:53:17 +0000683 return 0;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000684 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000685 return ((dictobject *)mp)->ma_used;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000686}
687
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000688PyObject *
689PyDict_Keys(mp)
690 PyObject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000691{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000692 if (mp == NULL || !PyDict_Check(mp)) {
693 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000694 return NULL;
695 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000696 return dict_keys((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000697}
698
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000699PyObject *
700PyDict_Values(mp)
701 PyObject *mp;
Guido van Rossum25831651993-05-19 14:50:45 +0000702{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000703 if (mp == NULL || !PyDict_Check(mp)) {
704 PyErr_BadInternalCall();
Guido van Rossum25831651993-05-19 14:50:45 +0000705 return NULL;
706 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000707 return dict_values((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum25831651993-05-19 14:50:45 +0000708}
709
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000710PyObject *
711PyDict_Items(mp)
712 PyObject *mp;
Guido van Rossum25831651993-05-19 14:50:45 +0000713{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000714 if (mp == NULL || !PyDict_Check(mp)) {
715 PyErr_BadInternalCall();
Guido van Rossum25831651993-05-19 14:50:45 +0000716 return NULL;
717 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000718 return dict_items((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum25831651993-05-19 14:50:45 +0000719}
720
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000721#define NEWCMP
722
723#ifdef NEWCMP
724
725/* Subroutine which returns the smallest key in a for which b's value
726 is different or absent. The value is returned too, through the
727 pval argument. No reference counts are incremented. */
728
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000729static PyObject *
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000730characterize(a, b, pval)
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000731 dictobject *a;
732 dictobject *b;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000733 PyObject **pval;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000734{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000735 PyObject *diff = NULL;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000736 int i;
737
738 *pval = NULL;
739 for (i = 0; i < a->ma_size; i++) {
740 if (a->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000741 PyObject *key = a->ma_table[i].me_key;
742 PyObject *aval, *bval;
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000743 /* XXX What if PyObject_Compare raises an exception? */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000744 if (diff != NULL && PyObject_Compare(key, diff) > 0)
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000745 continue;
746 aval = a->ma_table[i].me_value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000747 bval = PyDict_GetItem((PyObject *)b, key);
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000748 /* XXX What if PyObject_Compare raises an exception? */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000749 if (bval == NULL || PyObject_Compare(aval, bval) != 0)
750 {
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000751 diff = key;
752 *pval = aval;
753 }
754 }
755 }
756 return diff;
757}
758
759static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000760dict_compare(a, b)
761 dictobject *a, *b;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000762{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000763 PyObject *adiff, *bdiff, *aval, *bval;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000764 int res;
765
766 /* Compare lengths first */
767 if (a->ma_used < b->ma_used)
768 return -1; /* a is shorter */
769 else if (a->ma_used > b->ma_used)
770 return 1; /* b is shorter */
771 /* Same length -- check all keys */
772 adiff = characterize(a, b, &aval);
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000773 if (PyErr_Occurred())
774 return -1;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000775 if (adiff == NULL)
776 return 0; /* a is a subset with the same length */
777 bdiff = characterize(b, a, &bval);
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000778 if (PyErr_Occurred())
779 return -1;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000780 /* bdiff == NULL would be impossible now */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000781 res = PyObject_Compare(adiff, bdiff);
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000782 if (res == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000783 res = PyObject_Compare(aval, bval);
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000784 return res;
785}
786
787#else /* !NEWCMP */
788
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000789static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000790dict_compare(a, b)
791 dictobject *a, *b;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000792{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000793 PyObject *akeys, *bkeys;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000794 int i, n, res;
795 if (a == b)
796 return 0;
797 if (a->ma_used == 0) {
798 if (b->ma_used != 0)
799 return -1;
800 else
801 return 0;
802 }
803 else {
804 if (b->ma_used == 0)
805 return 1;
806 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000807 akeys = dict_keys(a, (PyObject *)NULL);
808 bkeys = dict_keys(b, (PyObject *)NULL);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000809 if (akeys == NULL || bkeys == NULL) {
810 /* Oops, out of memory -- what to do? */
811 /* For now, sort on address! */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000812 Py_XDECREF(akeys);
813 Py_XDECREF(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000814 if (a < b)
815 return -1;
816 else
817 return 1;
818 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000819 PyList_Sort(akeys);
820 PyList_Sort(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000821 n = a->ma_used < b->ma_used ? a->ma_used : b->ma_used; /* smallest */
822 res = 0;
823 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000824 PyObject *akey, *bkey, *aval, *bval;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000825 long ahash, bhash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000826 akey = PyList_GetItem(akeys, i);
827 bkey = PyList_GetItem(bkeys, i);
828 res = PyObject_Compare(akey, bkey);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000829 if (res != 0)
830 break;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000831#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000832 if (!PyString_Check(akey) ||
833 (ahash = ((PyStringObject *) akey)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000834#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000835 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000836 ahash = PyObject_Hash(akey);
Guido van Rossumca756f21997-01-23 19:39:29 +0000837 if (ahash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000838 PyErr_Clear(); /* Don't want errors here */
Guido van Rossumca756f21997-01-23 19:39:29 +0000839 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000840#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000841 if (!PyString_Check(bkey) ||
842 (bhash = ((PyStringObject *) bkey)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000843#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000844 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000845 bhash = PyObject_Hash(bkey);
Guido van Rossumca756f21997-01-23 19:39:29 +0000846 if (bhash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000847 PyErr_Clear(); /* Don't want errors here */
Guido van Rossumca756f21997-01-23 19:39:29 +0000848 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000849 aval = lookdict(a, akey, ahash) -> me_value;
850 bval = lookdict(b, bkey, bhash) -> me_value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000851 res = PyObject_Compare(aval, bval);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000852 if (res != 0)
853 break;
854 }
855 if (res == 0) {
856 if (a->ma_used < b->ma_used)
857 res = -1;
858 else if (a->ma_used > b->ma_used)
859 res = 1;
860 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000861 Py_DECREF(akeys);
862 Py_DECREF(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000863 return res;
864}
865
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000866#endif /* !NEWCMP */
867
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000868static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000869dict_has_key(mp, args)
870 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000871 PyObject *args;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000872{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000873 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000874 long hash;
875 register long ok;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000876 if (!PyArg_Parse(args, "O", &key))
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000877 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000878#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000879 if (!PyString_Check(key) ||
880 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000881#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000882 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000883 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000884 if (hash == -1)
885 return NULL;
886 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000887 ok = mp->ma_size != 0 && lookdict(mp, key, hash)->me_value != NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000888 return PyInt_FromLong(ok);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000889}
890
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000891static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000892dict_clear(mp, args)
893 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000894 PyObject *args;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000895{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000896 if (!PyArg_NoArgs(args))
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000897 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000898 PyDict_Clear((PyObject *)mp);
899 Py_INCREF(Py_None);
900 return Py_None;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000901}
902
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903static PyMethodDef mapp_methods[] = {
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000904 {"clear", (PyCFunction)dict_clear},
905 {"has_key", (PyCFunction)dict_has_key},
906 {"items", (PyCFunction)dict_items},
907 {"keys", (PyCFunction)dict_keys},
908 {"values", (PyCFunction)dict_values},
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000909 {NULL, NULL} /* sentinel */
910};
911
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000912static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000913dict_getattr(mp, name)
914 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000915 char *name;
916{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000917 return Py_FindMethod(mapp_methods, (PyObject *)mp, name);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000918}
919
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000920PyTypeObject PyDict_Type = {
921 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000922 0,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000923 "dictionary",
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000924 sizeof(dictobject),
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000925 0,
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000926 (destructor)dict_dealloc, /*tp_dealloc*/
927 (printfunc)dict_print, /*tp_print*/
928 (getattrfunc)dict_getattr, /*tp_getattr*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000929 0, /*tp_setattr*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000930 (cmpfunc)dict_compare, /*tp_compare*/
931 (reprfunc)dict_repr, /*tp_repr*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000932 0, /*tp_as_number*/
933 0, /*tp_as_sequence*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000934 &dict_as_mapping, /*tp_as_mapping*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000935};
936
Guido van Rossum3cca2451997-05-16 14:23:33 +0000937/* For backward compatibility with old dictionary interface */
938
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000939PyObject *
940PyDict_GetItemString(v, key)
941 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000942 char *key;
943{
Guido van Rossum3cca2451997-05-16 14:23:33 +0000944 PyObject *kv, *rv;
945 kv = PyString_FromString(key);
946 if (kv == NULL)
947 return NULL;
948 PyString_InternInPlace(&kv);
949 rv = PyDict_GetItem(v, kv);
950 Py_DECREF(kv);
951 return rv;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000952}
953
954int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000955PyDict_SetItemString(v, key, item)
956 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000957 char *key;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000958 PyObject *item;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000959{
Guido van Rossum3cca2451997-05-16 14:23:33 +0000960 PyObject *kv;
961 int err;
962 kv = PyString_FromString(key);
963 if (kv == NULL)
Guido van Rossum037b2201997-05-20 18:35:19 +0000964 return -1;
Guido van Rossum3cca2451997-05-16 14:23:33 +0000965 PyString_InternInPlace(&kv);
966 err = PyDict_SetItem(v, kv, item);
967 Py_DECREF(kv);
968 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000969}
970
971int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000972PyDict_DelItemString(v, key)
973 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000974 char *key;
975{
Guido van Rossum3cca2451997-05-16 14:23:33 +0000976 PyObject *kv;
977 int err;
978 kv = PyString_FromString(key);
979 if (kv == NULL)
Guido van Rossum037b2201997-05-20 18:35:19 +0000980 return -1;
Guido van Rossum3cca2451997-05-16 14:23:33 +0000981 PyString_InternInPlace(&kv);
982 err = PyDict_DelItem(v, kv);
983 Py_DECREF(kv);
984 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000985}