blob: 91af7287e4ad1b624b12584baa9b406239d0fd60 [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 Rossumefb46091997-01-29 15:53:56 +0000187 /* Derive incr from sum, just to make it more arbitrary. Note that
Guido van Rossum16e93a81997-01-28 00:00:11 +0000188 incr must not be 0, or we will get into an infinite loop.*/
Guido van Rossumefb46091997-01-29 15:53:56 +0000189 incr = (sum ^ (sum >> 3)) & mask;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000190 if (!incr)
191 incr = mask;
192 if (incr > mask) /* Cycle through GF(2^n)-{0} */
193 incr ^= mp->ma_poly; /* This will implicitly clear the
194 highest bit */
195 for (;;) {
Guido van Rossumefb46091997-01-29 15:53:56 +0000196 ep = &ep0[(i+incr)&mask];
Guido van Rossum16e93a81997-01-28 00:00:11 +0000197 if (ep->me_key == NULL) {
198 if (freeslot != NULL)
199 return freeslot;
200 else
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000201 return ep;
202 }
Guido van Rossum16e93a81997-01-28 00:00:11 +0000203 if (ep->me_key == dummy) {
204 if (freeslot == NULL)
205 freeslot = ep;
206 }
207 else if (ep->me_key == key ||
208 (ep->me_hash == hash &&
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000209 PyObject_Compare(ep->me_key, key) == 0)) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000210 return ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000211 }
212 /* Cycle through GF(2^n)-{0} */
213 incr = incr << 1;
214 if (incr > mask)
215 incr ^= mp->ma_poly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000216 }
217}
218
219/*
220Internal routine to insert a new item into the table.
221Used both by the internal resize routine and by the public insert routine.
222Eats a reference to key and one to value.
223*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000224static void insertdict
225 Py_PROTO((dictobject *, PyObject *, long, PyObject *));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000226static void
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000227insertdict(mp, key, hash, value)
228 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000229 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000230 long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231 PyObject *value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000232{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 PyObject *old_value;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000234 register dictentry *ep;
235 ep = lookdict(mp, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000236 if (ep->me_value != NULL) {
Guido van Rossumd7047b31995-01-02 19:07:15 +0000237 old_value = ep->me_value;
238 ep->me_value = value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000239 Py_DECREF(old_value); /* which **CAN** re-enter */
240 Py_DECREF(key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000241 }
242 else {
243 if (ep->me_key == NULL)
244 mp->ma_fill++;
245 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000246 Py_DECREF(ep->me_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000247 ep->me_key = key;
248 ep->me_hash = hash;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000249 ep->me_value = value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000250 mp->ma_used++;
251 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000252}
253
254/*
255Restructure the table by allocating a new table and reinserting all
256items again. When entries have been deleted, the new table may
257actually be smaller than the old one.
258*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000259static int dictresize Py_PROTO((dictobject *));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000260static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000261dictresize(mp)
262 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000263{
264 register int oldsize = mp->ma_size;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000265 register int newsize, newpoly;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000266 register dictentry *oldtable = mp->ma_table;
267 register dictentry *newtable;
268 register dictentry *ep;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000269 register int i;
270 newsize = mp->ma_size;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000271 for (i = 0, newsize = MINSIZE; ; i++, newsize <<= 1) {
272 if (i > sizeof(polys)/sizeof(polys[0])) {
273 /* Ran out of polynomials */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000274 PyErr_NoMemory();
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000275 return -1;
276 }
Guido van Rossum16e93a81997-01-28 00:00:11 +0000277 if (newsize > mp->ma_used*2) {
278 newpoly = polys[i];
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000279 break;
280 }
281 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000282 newtable = (dictentry *) calloc(sizeof(dictentry), newsize);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000283 if (newtable == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000284 PyErr_NoMemory();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000285 return -1;
286 }
287 mp->ma_size = newsize;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000288 mp->ma_poly = newpoly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000289 mp->ma_table = newtable;
290 mp->ma_fill = 0;
291 mp->ma_used = 0;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000292
293 /* Make two passes, so we can avoid decrefs
294 (and possible side effects) till the table is copied */
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000295 for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
296 if (ep->me_value != NULL)
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000297 insertdict(mp,ep->me_key,ep->me_hash,ep->me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000298 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000299 for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
300 if (ep->me_value == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000301 Py_XDECREF(ep->me_key);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000302 }
303
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000304 PyMem_XDEL(oldtable);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000305 return 0;
306}
307
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000308PyObject *
309PyDict_GetItem(op, key)
310 PyObject *op;
311 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000312{
313 long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000314 if (!PyDict_Check(op)) {
315 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000316 return NULL;
317 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000318 if (((dictobject *)op)->ma_table == NULL)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000319 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000320#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000321 if (!PyString_Check(key) ||
322 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000323#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000324 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000325 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000326 if (hash == -1)
327 return NULL;
328 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000329 return lookdict((dictobject *)op, key, hash) -> me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000330}
331
332int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000333PyDict_SetItem(op, key, value)
334 register PyObject *op;
335 PyObject *key;
336 PyObject *value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000337{
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000338 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000339 register long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340 if (!PyDict_Check(op)) {
341 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000342 return -1;
343 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000344 mp = (dictobject *)op;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000345#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346 if (PyString_Check(key)) {
Guido van Rossum2a61e741997-01-18 07:55:05 +0000347#ifdef INTERN_STRINGS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000348 if (((PyStringObject *)key)->ob_sinterned != NULL) {
349 key = ((PyStringObject *)key)->ob_sinterned;
350 hash = ((PyStringObject *)key)->ob_shash;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000351 }
352 else
353#endif
354 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000355 hash = ((PyStringObject *)key)->ob_shash;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000356 if (hash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000357 hash = PyObject_Hash(key);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000358 }
359 }
360 else
361#endif
362 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000363 hash = PyObject_Hash(key);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000364 if (hash == -1)
365 return -1;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000366 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000367 /* if fill >= 2/3 size, resize */
368 if (mp->ma_fill*3 >= mp->ma_size*2) {
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000369 if (dictresize(mp) != 0) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000370 if (mp->ma_fill+1 > mp->ma_size)
371 return -1;
372 }
373 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000374 Py_INCREF(value);
375 Py_INCREF(key);
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000376 insertdict(mp, key, hash, value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000377 return 0;
378}
379
380int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000381PyDict_DelItem(op, key)
382 PyObject *op;
383 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000384{
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000385 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000386 register long hash;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000387 register dictentry *ep;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000388 PyObject *old_value, *old_key;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000389
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390 if (!PyDict_Check(op)) {
391 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000392 return -1;
393 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000394#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000395 if (!PyString_Check(key) ||
396 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000397#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000398 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000399 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000400 if (hash == -1)
401 return -1;
402 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000403 mp = (dictobject *)op;
404 if (((dictobject *)op)->ma_table == NULL)
Guido van Rossumefc87131995-01-02 19:42:39 +0000405 goto empty;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000406 ep = lookdict(mp, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000407 if (ep->me_value == NULL) {
Guido van Rossumefc87131995-01-02 19:42:39 +0000408 empty:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000409 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000410 return -1;
411 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000412 old_key = ep->me_key;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000413 Py_INCREF(dummy);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000414 ep->me_key = dummy;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000415 old_value = ep->me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000416 ep->me_value = NULL;
417 mp->ma_used--;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000418 Py_DECREF(old_value);
419 Py_DECREF(old_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000420 return 0;
421}
422
Guido van Rossum25831651993-05-19 14:50:45 +0000423void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000424PyDict_Clear(op)
425 PyObject *op;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000426{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000427 int i, n;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000428 register dictentry *table;
429 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000430 if (!PyDict_Check(op))
Guido van Rossum25831651993-05-19 14:50:45 +0000431 return;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000432 mp = (dictobject *)op;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000433 table = mp->ma_table;
434 if (table == NULL)
435 return;
436 n = mp->ma_size;
437 mp->ma_size = mp->ma_used = mp->ma_fill = 0;
438 mp->ma_table = NULL;
439 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000440 Py_XDECREF(table[i].me_key);
441 Py_XDECREF(table[i].me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000442 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000443 PyMem_DEL(table);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000444}
445
Guido van Rossum25831651993-05-19 14:50:45 +0000446int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000447PyDict_Next(op, ppos, pkey, pvalue)
448 PyObject *op;
Guido van Rossum25831651993-05-19 14:50:45 +0000449 int *ppos;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000450 PyObject **pkey;
451 PyObject **pvalue;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000452{
Guido van Rossum25831651993-05-19 14:50:45 +0000453 int i;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000454 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000455 if (!PyDict_Check(op))
Guido van Rossum25831651993-05-19 14:50:45 +0000456 return 0;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000457 mp = (dictobject *)op;
Guido van Rossum25831651993-05-19 14:50:45 +0000458 i = *ppos;
459 if (i < 0)
460 return 0;
461 while (i < mp->ma_size && mp->ma_table[i].me_value == NULL)
462 i++;
463 *ppos = i+1;
464 if (i >= mp->ma_size)
465 return 0;
466 if (pkey)
467 *pkey = mp->ma_table[i].me_key;
468 if (pvalue)
469 *pvalue = mp->ma_table[i].me_value;
470 return 1;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000471}
472
473/* Methods */
474
475static void
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000476dict_dealloc(mp)
477 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000478{
479 register int i;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000480 register dictentry *ep;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000481 for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) {
482 if (ep->me_key != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000483 Py_DECREF(ep->me_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000484 if (ep->me_value != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000485 Py_DECREF(ep->me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000486 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000487 PyMem_XDEL(mp->ma_table);
488 PyMem_DEL(mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000489}
490
491static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000492dict_print(mp, fp, flags)
493 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000494 register FILE *fp;
495 register int flags;
496{
497 register int i;
498 register int any;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000499 register dictentry *ep;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000500 fprintf(fp, "{");
501 any = 0;
502 for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) {
503 if (ep->me_value != NULL) {
504 if (any++ > 0)
505 fprintf(fp, ", ");
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000506 if (PyObject_Print((PyObject *)ep->me_key, fp, 0) != 0)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000507 return -1;
508 fprintf(fp, ": ");
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000509 if (PyObject_Print(ep->me_value, fp, 0) != 0)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000510 return -1;
511 }
512 }
513 fprintf(fp, "}");
514 return 0;
515}
516
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000517static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000518dict_repr(mp)
519 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000520{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000521 auto PyObject *v;
522 PyObject *sepa, *colon;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000523 register int i;
524 register int any;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000525 register dictentry *ep;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000526 v = PyString_FromString("{");
527 sepa = PyString_FromString(", ");
528 colon = PyString_FromString(": ");
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000529 any = 0;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000530 for (i = 0, ep = mp->ma_table; i < mp->ma_size && v; i++, ep++) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000531 if (ep->me_value != NULL) {
532 if (any++)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000533 PyString_Concat(&v, sepa);
534 PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_key));
535 PyString_Concat(&v, colon);
536 PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_value));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000537 }
538 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000539 PyString_ConcatAndDel(&v, PyString_FromString("}"));
540 Py_XDECREF(sepa);
541 Py_XDECREF(colon);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000542 return v;
543}
544
545static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000546dict_length(mp)
547 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000548{
549 return mp->ma_used;
550}
551
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000552static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000553dict_subscript(mp, key)
554 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000555 register PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000556{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000557 PyObject *v;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000558 long hash;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000559 if (mp->ma_table == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000560 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000561 return NULL;
562 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000563#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000564 if (!PyString_Check(key) ||
565 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000566#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000567 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000568 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000569 if (hash == -1)
570 return NULL;
571 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000572 v = lookdict(mp, key, hash) -> me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000573 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000574 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000575 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000576 Py_INCREF(v);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000577 return v;
578}
579
580static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000581dict_ass_sub(mp, v, w)
582 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000583 PyObject *v, *w;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000584{
585 if (w == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000586 return PyDict_DelItem((PyObject *)mp, v);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000587 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000588 return PyDict_SetItem((PyObject *)mp, v, w);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000589}
590
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000591static PyMappingMethods dict_as_mapping = {
592 (inquiry)dict_length, /*mp_length*/
593 (binaryfunc)dict_subscript, /*mp_subscript*/
594 (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000595};
596
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000597static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000598dict_keys(mp, args)
599 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000600 PyObject *args;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000601{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000602 register PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000603 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604 if (!PyArg_NoArgs(args))
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000605 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000606 v = PyList_New(mp->ma_used);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000607 if (v == NULL)
608 return NULL;
609 for (i = 0, j = 0; i < mp->ma_size; i++) {
610 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000611 PyObject *key = mp->ma_table[i].me_key;
612 Py_INCREF(key);
613 PyList_SetItem(v, j, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000614 j++;
615 }
616 }
617 return v;
618}
619
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000620static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000621dict_values(mp, args)
622 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000623 PyObject *args;
Guido van Rossum25831651993-05-19 14:50:45 +0000624{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 register PyObject *v;
Guido van Rossum25831651993-05-19 14:50:45 +0000626 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 if (!PyArg_NoArgs(args))
Guido van Rossum25831651993-05-19 14:50:45 +0000628 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000629 v = PyList_New(mp->ma_used);
Guido van Rossum25831651993-05-19 14:50:45 +0000630 if (v == NULL)
631 return NULL;
632 for (i = 0, j = 0; i < mp->ma_size; i++) {
633 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000634 PyObject *value = mp->ma_table[i].me_value;
635 Py_INCREF(value);
636 PyList_SetItem(v, j, value);
Guido van Rossum25831651993-05-19 14:50:45 +0000637 j++;
638 }
639 }
640 return v;
641}
642
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000643static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000644dict_items(mp, args)
645 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000646 PyObject *args;
Guido van Rossum25831651993-05-19 14:50:45 +0000647{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000648 register PyObject *v;
Guido van Rossum25831651993-05-19 14:50:45 +0000649 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000650 if (!PyArg_NoArgs(args))
Guido van Rossum25831651993-05-19 14:50:45 +0000651 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000652 v = PyList_New(mp->ma_used);
Guido van Rossum25831651993-05-19 14:50:45 +0000653 if (v == NULL)
654 return NULL;
655 for (i = 0, j = 0; i < mp->ma_size; i++) {
656 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000657 PyObject *key = mp->ma_table[i].me_key;
658 PyObject *value = mp->ma_table[i].me_value;
659 PyObject *item = PyTuple_New(2);
Guido van Rossum25831651993-05-19 14:50:45 +0000660 if (item == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000661 Py_DECREF(v);
Guido van Rossum25831651993-05-19 14:50:45 +0000662 return NULL;
663 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000664 Py_INCREF(key);
665 PyTuple_SetItem(item, 0, key);
666 Py_INCREF(value);
667 PyTuple_SetItem(item, 1, value);
668 PyList_SetItem(v, j, item);
Guido van Rossum25831651993-05-19 14:50:45 +0000669 j++;
670 }
671 }
672 return v;
673}
674
Guido van Rossum4199fac1993-11-05 10:18:44 +0000675int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000676PyDict_Size(mp)
677 PyObject *mp;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000678{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000679 if (mp == NULL || !PyDict_Check(mp)) {
680 PyErr_BadInternalCall();
Guido van Rossumb376a4a1993-11-23 17:53:17 +0000681 return 0;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000682 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000683 return ((dictobject *)mp)->ma_used;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000684}
685
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000686PyObject *
687PyDict_Keys(mp)
688 PyObject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000689{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000690 if (mp == NULL || !PyDict_Check(mp)) {
691 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000692 return NULL;
693 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000694 return dict_keys((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000695}
696
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000697PyObject *
698PyDict_Values(mp)
699 PyObject *mp;
Guido van Rossum25831651993-05-19 14:50:45 +0000700{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000701 if (mp == NULL || !PyDict_Check(mp)) {
702 PyErr_BadInternalCall();
Guido van Rossum25831651993-05-19 14:50:45 +0000703 return NULL;
704 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000705 return dict_values((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum25831651993-05-19 14:50:45 +0000706}
707
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000708PyObject *
709PyDict_Items(mp)
710 PyObject *mp;
Guido van Rossum25831651993-05-19 14:50:45 +0000711{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000712 if (mp == NULL || !PyDict_Check(mp)) {
713 PyErr_BadInternalCall();
Guido van Rossum25831651993-05-19 14:50:45 +0000714 return NULL;
715 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000716 return dict_items((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum25831651993-05-19 14:50:45 +0000717}
718
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000719#define NEWCMP
720
721#ifdef NEWCMP
722
723/* Subroutine which returns the smallest key in a for which b's value
724 is different or absent. The value is returned too, through the
725 pval argument. No reference counts are incremented. */
726
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000727static PyObject *
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000728characterize(a, b, pval)
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000729 dictobject *a;
730 dictobject *b;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000731 PyObject **pval;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000732{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000733 PyObject *diff = NULL;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000734 int i;
735
736 *pval = NULL;
737 for (i = 0; i < a->ma_size; i++) {
738 if (a->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000739 PyObject *key = a->ma_table[i].me_key;
740 PyObject *aval, *bval;
741 if (diff != NULL && PyObject_Compare(key, diff) > 0)
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000742 continue;
743 aval = a->ma_table[i].me_value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000744 bval = PyDict_GetItem((PyObject *)b, key);
745 if (bval == NULL || PyObject_Compare(aval, bval) != 0)
746 {
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000747 diff = key;
748 *pval = aval;
749 }
750 }
751 }
752 return diff;
753}
754
755static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000756dict_compare(a, b)
757 dictobject *a, *b;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000758{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000759 PyObject *adiff, *bdiff, *aval, *bval;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000760 int res;
761
762 /* Compare lengths first */
763 if (a->ma_used < b->ma_used)
764 return -1; /* a is shorter */
765 else if (a->ma_used > b->ma_used)
766 return 1; /* b is shorter */
767 /* Same length -- check all keys */
768 adiff = characterize(a, b, &aval);
769 if (adiff == NULL)
770 return 0; /* a is a subset with the same length */
771 bdiff = characterize(b, a, &bval);
772 /* bdiff == NULL would be impossible now */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000773 res = PyObject_Compare(adiff, bdiff);
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000774 if (res == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000775 res = PyObject_Compare(aval, bval);
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000776 return res;
777}
778
779#else /* !NEWCMP */
780
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000781static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000782dict_compare(a, b)
783 dictobject *a, *b;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000784{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000785 PyObject *akeys, *bkeys;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000786 int i, n, res;
787 if (a == b)
788 return 0;
789 if (a->ma_used == 0) {
790 if (b->ma_used != 0)
791 return -1;
792 else
793 return 0;
794 }
795 else {
796 if (b->ma_used == 0)
797 return 1;
798 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000799 akeys = dict_keys(a, (PyObject *)NULL);
800 bkeys = dict_keys(b, (PyObject *)NULL);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000801 if (akeys == NULL || bkeys == NULL) {
802 /* Oops, out of memory -- what to do? */
803 /* For now, sort on address! */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000804 Py_XDECREF(akeys);
805 Py_XDECREF(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000806 if (a < b)
807 return -1;
808 else
809 return 1;
810 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000811 PyList_Sort(akeys);
812 PyList_Sort(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000813 n = a->ma_used < b->ma_used ? a->ma_used : b->ma_used; /* smallest */
814 res = 0;
815 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000816 PyObject *akey, *bkey, *aval, *bval;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000817 long ahash, bhash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000818 akey = PyList_GetItem(akeys, i);
819 bkey = PyList_GetItem(bkeys, i);
820 res = PyObject_Compare(akey, bkey);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000821 if (res != 0)
822 break;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000823#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000824 if (!PyString_Check(akey) ||
825 (ahash = ((PyStringObject *) akey)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000826#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000827 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000828 ahash = PyObject_Hash(akey);
Guido van Rossumca756f21997-01-23 19:39:29 +0000829 if (ahash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000830 PyErr_Clear(); /* Don't want errors here */
Guido van Rossumca756f21997-01-23 19:39:29 +0000831 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000832#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000833 if (!PyString_Check(bkey) ||
834 (bhash = ((PyStringObject *) bkey)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000835#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000836 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000837 bhash = PyObject_Hash(bkey);
Guido van Rossumca756f21997-01-23 19:39:29 +0000838 if (bhash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000839 PyErr_Clear(); /* Don't want errors here */
Guido van Rossumca756f21997-01-23 19:39:29 +0000840 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000841 aval = lookdict(a, akey, ahash) -> me_value;
842 bval = lookdict(b, bkey, bhash) -> me_value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000843 res = PyObject_Compare(aval, bval);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000844 if (res != 0)
845 break;
846 }
847 if (res == 0) {
848 if (a->ma_used < b->ma_used)
849 res = -1;
850 else if (a->ma_used > b->ma_used)
851 res = 1;
852 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000853 Py_DECREF(akeys);
854 Py_DECREF(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000855 return res;
856}
857
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000858#endif /* !NEWCMP */
859
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000860static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000861dict_has_key(mp, args)
862 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000863 PyObject *args;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000864{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000865 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000866 long hash;
867 register long ok;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000868 if (!PyArg_Parse(args, "O", &key))
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000869 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000870#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000871 if (!PyString_Check(key) ||
872 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000873#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000874 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000875 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000876 if (hash == -1)
877 return NULL;
878 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000879 ok = mp->ma_size != 0 && lookdict(mp, key, hash)->me_value != NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000880 return PyInt_FromLong(ok);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000881}
882
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000883static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000884dict_clear(mp, args)
885 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000886 PyObject *args;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000887{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000888 if (!PyArg_NoArgs(args))
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000889 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000890 PyDict_Clear((PyObject *)mp);
891 Py_INCREF(Py_None);
892 return Py_None;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000893}
894
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000895static PyMethodDef mapp_methods[] = {
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000896 {"clear", (PyCFunction)dict_clear},
897 {"has_key", (PyCFunction)dict_has_key},
898 {"items", (PyCFunction)dict_items},
899 {"keys", (PyCFunction)dict_keys},
900 {"values", (PyCFunction)dict_values},
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000901 {NULL, NULL} /* sentinel */
902};
903
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000904static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000905dict_getattr(mp, name)
906 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000907 char *name;
908{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000909 return Py_FindMethod(mapp_methods, (PyObject *)mp, name);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000910}
911
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000912PyTypeObject PyDict_Type = {
913 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000914 0,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000915 "dictionary",
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000916 sizeof(dictobject),
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000917 0,
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000918 (destructor)dict_dealloc, /*tp_dealloc*/
919 (printfunc)dict_print, /*tp_print*/
920 (getattrfunc)dict_getattr, /*tp_getattr*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000921 0, /*tp_setattr*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000922 (cmpfunc)dict_compare, /*tp_compare*/
923 (reprfunc)dict_repr, /*tp_repr*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000924 0, /*tp_as_number*/
925 0, /*tp_as_sequence*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000926 &dict_as_mapping, /*tp_as_mapping*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000927};
928
Guido van Rossum3cca2451997-05-16 14:23:33 +0000929/* For backward compatibility with old dictionary interface */
930
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000931PyObject *
932PyDict_GetItemString(v, key)
933 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000934 char *key;
935{
Guido van Rossum3cca2451997-05-16 14:23:33 +0000936 PyObject *kv, *rv;
937 kv = PyString_FromString(key);
938 if (kv == NULL)
939 return NULL;
940 PyString_InternInPlace(&kv);
941 rv = PyDict_GetItem(v, kv);
942 Py_DECREF(kv);
943 return rv;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000944}
945
946int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000947PyDict_SetItemString(v, key, item)
948 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000949 char *key;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000950 PyObject *item;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000951{
Guido van Rossum3cca2451997-05-16 14:23:33 +0000952 PyObject *kv;
953 int err;
954 kv = PyString_FromString(key);
955 if (kv == NULL)
Guido van Rossum037b2201997-05-20 18:35:19 +0000956 return -1;
Guido van Rossum3cca2451997-05-16 14:23:33 +0000957 PyString_InternInPlace(&kv);
958 err = PyDict_SetItem(v, kv, item);
959 Py_DECREF(kv);
960 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000961}
962
963int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000964PyDict_DelItemString(v, key)
965 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000966 char *key;
967{
Guido van Rossum3cca2451997-05-16 14:23:33 +0000968 PyObject *kv;
969 int err;
970 kv = PyString_FromString(key);
971 if (kv == NULL)
Guido van Rossum037b2201997-05-20 18:35:19 +0000972 return -1;
Guido van Rossum3cca2451997-05-16 14:23:33 +0000973 PyString_InternInPlace(&kv);
974 err = PyDict_DelItem(v, kv);
975 Py_DECREF(kv);
976 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000977}