blob: 7b6225865b718dc7e33d78cb5146f6398dbd143d [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
Guido van Rossumfd7a0b81997-08-18 21:52:47 +0000154Jyrki Alakuijala and Vladimir Marangozov.)
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 Rossumfd7a0b81997-08-18 21:52:47 +0000161 register long hash;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000162{
Guido van Rossum16e93a81997-01-28 00:00:11 +0000163 register int i;
164 register unsigned incr;
Guido van Rossumfd7a0b81997-08-18 21:52:47 +0000165 register dictentry *freeslot;
Guido van Rossum2095d241997-04-09 19:41:24 +0000166 register unsigned int mask = mp->ma_size-1;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000167 dictentry *ep0 = mp->ma_table;
168 register dictentry *ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000169 /* We must come up with (i, incr) such that 0 <= i < ma_size
170 and 0 < incr < ma_size and both are a function of hash */
Guido van Rossumfd7a0b81997-08-18 21:52:47 +0000171 i = (~hash) & mask;
172 /* We use ~hash instead of hash, as degenerate hash functions, such
Guido van Rossum16e93a81997-01-28 00:00:11 +0000173 as for ints <sigh>, can have lots of leading zeros. It's not
174 really a performance risk, but better safe than sorry. */
Guido van Rossumefb46091997-01-29 15:53:56 +0000175 ep = &ep0[i];
Guido van Rossum16e93a81997-01-28 00:00:11 +0000176 if (ep->me_key == NULL)
Guido van Rossum7d181591997-01-16 21:06:45 +0000177 return ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000178 if (ep->me_key == dummy)
Guido van Rossum7d181591997-01-16 21:06:45 +0000179 freeslot = ep;
Guido van Rossumfd7a0b81997-08-18 21:52:47 +0000180 else {
181 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))
Guido van Rossumfd7a0b81997-08-18 21:52:47 +0000184 {
185 return ep;
186 }
187 freeslot = NULL;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000188 }
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000189 /* XXX What if PyObject_Compare returned an exception? */
Guido van Rossumefb46091997-01-29 15:53:56 +0000190 /* Derive incr from sum, just to make it more arbitrary. Note that
Guido van Rossum16e93a81997-01-28 00:00:11 +0000191 incr must not be 0, or we will get into an infinite loop.*/
Guido van Rossumfd7a0b81997-08-18 21:52:47 +0000192 incr = (hash ^ ((unsigned long)hash >> 3)) & mask;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000193 if (!incr)
194 incr = mask;
Guido van Rossumfd7a0b81997-08-18 21:52:47 +0000195 else if (incr > mask) /* Cycle through GF(2^n)-{0} */
Guido van Rossum16e93a81997-01-28 00:00:11 +0000196 incr ^= mp->ma_poly; /* This will implicitly clear the
197 highest bit */
198 for (;;) {
Guido van Rossumefb46091997-01-29 15:53:56 +0000199 ep = &ep0[(i+incr)&mask];
Guido van Rossum16e93a81997-01-28 00:00:11 +0000200 if (ep->me_key == NULL) {
201 if (freeslot != NULL)
202 return freeslot;
203 else
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000204 return ep;
205 }
Guido van Rossum16e93a81997-01-28 00:00:11 +0000206 if (ep->me_key == dummy) {
207 if (freeslot == NULL)
208 freeslot = ep;
209 }
210 else if (ep->me_key == key ||
211 (ep->me_hash == hash &&
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000212 PyObject_Compare(ep->me_key, key) == 0)) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000213 return ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000214 }
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000215 /* XXX What if PyObject_Compare returned an exception? */
Guido van Rossum16e93a81997-01-28 00:00:11 +0000216 /* Cycle through GF(2^n)-{0} */
217 incr = incr << 1;
218 if (incr > mask)
219 incr ^= mp->ma_poly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000220 }
221}
222
223/*
224Internal routine to insert a new item into the table.
225Used both by the internal resize routine and by the public insert routine.
226Eats a reference to key and one to value.
227*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000228static void insertdict
229 Py_PROTO((dictobject *, PyObject *, long, PyObject *));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000230static void
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000231insertdict(mp, key, hash, value)
232 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000234 long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235 PyObject *value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000236{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 PyObject *old_value;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000238 register dictentry *ep;
239 ep = lookdict(mp, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000240 if (ep->me_value != NULL) {
Guido van Rossumd7047b31995-01-02 19:07:15 +0000241 old_value = ep->me_value;
242 ep->me_value = value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000243 Py_DECREF(old_value); /* which **CAN** re-enter */
244 Py_DECREF(key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000245 }
246 else {
247 if (ep->me_key == NULL)
248 mp->ma_fill++;
249 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000250 Py_DECREF(ep->me_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000251 ep->me_key = key;
252 ep->me_hash = hash;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000253 ep->me_value = value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000254 mp->ma_used++;
255 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000256}
257
258/*
259Restructure the table by allocating a new table and reinserting all
260items again. When entries have been deleted, the new table may
261actually be smaller than the old one.
262*/
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000263static int dictresize Py_PROTO((dictobject *, int));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000264static int
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000265dictresize(mp, minused)
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000266 dictobject *mp;
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000267 int minused;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000268{
269 register int oldsize = mp->ma_size;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000270 register int newsize, newpoly;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000271 register dictentry *oldtable = mp->ma_table;
272 register dictentry *newtable;
273 register dictentry *ep;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000274 register int i;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000275 for (i = 0, newsize = MINSIZE; ; i++, newsize <<= 1) {
276 if (i > sizeof(polys)/sizeof(polys[0])) {
277 /* Ran out of polynomials */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000278 PyErr_NoMemory();
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000279 return -1;
280 }
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000281 if (newsize > minused) {
Guido van Rossum16e93a81997-01-28 00:00:11 +0000282 newpoly = polys[i];
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000283 break;
284 }
285 }
Guido van Rossum0fd00331998-07-16 15:06:13 +0000286 newtable = (dictentry *) malloc(sizeof(dictentry) * newsize);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000287 if (newtable == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000288 PyErr_NoMemory();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000289 return -1;
290 }
Guido van Rossum0fd00331998-07-16 15:06:13 +0000291 memset(newtable, '\0', sizeof(dictentry) * newsize);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000292 mp->ma_size = newsize;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000293 mp->ma_poly = newpoly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000294 mp->ma_table = newtable;
295 mp->ma_fill = 0;
296 mp->ma_used = 0;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000297
298 /* Make two passes, so we can avoid decrefs
299 (and possible side effects) till the table is copied */
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000300 for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
301 if (ep->me_value != NULL)
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000302 insertdict(mp,ep->me_key,ep->me_hash,ep->me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000303 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000304 for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
Guido van Rossum255443b1998-04-10 22:47:14 +0000305 if (ep->me_value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306 Py_XDECREF(ep->me_key);
Guido van Rossum255443b1998-04-10 22:47:14 +0000307 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000308 }
309
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310 PyMem_XDEL(oldtable);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000311 return 0;
312}
313
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000314PyObject *
315PyDict_GetItem(op, key)
316 PyObject *op;
317 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000318{
319 long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000320 if (!PyDict_Check(op)) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000321 return NULL;
322 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000323 if (((dictobject *)op)->ma_table == NULL)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000324 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000325#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000326 if (!PyString_Check(key) ||
327 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000328#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000329 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000330 hash = PyObject_Hash(key);
Guido van Rossum474b19e1998-05-14 01:00:51 +0000331 if (hash == -1) {
332 PyErr_Clear();
Guido van Rossumca756f21997-01-23 19:39:29 +0000333 return NULL;
Guido van Rossum474b19e1998-05-14 01:00:51 +0000334 }
Guido van Rossumca756f21997-01-23 19:39:29 +0000335 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000336 return lookdict((dictobject *)op, key, hash) -> me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000337}
338
339int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340PyDict_SetItem(op, key, value)
341 register PyObject *op;
342 PyObject *key;
343 PyObject *value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000344{
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000345 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000346 register long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347 if (!PyDict_Check(op)) {
348 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000349 return -1;
350 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000351 mp = (dictobject *)op;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000352#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000353 if (PyString_Check(key)) {
Guido van Rossum2a61e741997-01-18 07:55:05 +0000354#ifdef INTERN_STRINGS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000355 if (((PyStringObject *)key)->ob_sinterned != NULL) {
356 key = ((PyStringObject *)key)->ob_sinterned;
357 hash = ((PyStringObject *)key)->ob_shash;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000358 }
359 else
360#endif
361 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000362 hash = ((PyStringObject *)key)->ob_shash;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000363 if (hash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000364 hash = PyObject_Hash(key);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000365 }
366 }
367 else
368#endif
369 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000370 hash = PyObject_Hash(key);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000371 if (hash == -1)
372 return -1;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000373 }
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000374 /* if fill >= 2/3 size, double in size */
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000375 if (mp->ma_fill*3 >= mp->ma_size*2) {
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000376 if (dictresize(mp, mp->ma_used*2) != 0) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000377 if (mp->ma_fill+1 > mp->ma_size)
378 return -1;
379 }
380 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000381 Py_INCREF(value);
382 Py_INCREF(key);
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000383 insertdict(mp, key, hash, value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000384 return 0;
385}
386
387int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000388PyDict_DelItem(op, key)
389 PyObject *op;
390 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000391{
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000392 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000393 register long hash;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000394 register dictentry *ep;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000395 PyObject *old_value, *old_key;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000396
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000397 if (!PyDict_Check(op)) {
398 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000399 return -1;
400 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000401#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000402 if (!PyString_Check(key) ||
403 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000404#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000405 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000406 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000407 if (hash == -1)
408 return -1;
409 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000410 mp = (dictobject *)op;
411 if (((dictobject *)op)->ma_table == NULL)
Guido van Rossumefc87131995-01-02 19:42:39 +0000412 goto empty;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000413 ep = lookdict(mp, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000414 if (ep->me_value == NULL) {
Guido van Rossumefc87131995-01-02 19:42:39 +0000415 empty:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000416 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000417 return -1;
418 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000419 old_key = ep->me_key;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000420 Py_INCREF(dummy);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000421 ep->me_key = dummy;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000422 old_value = ep->me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000423 ep->me_value = NULL;
424 mp->ma_used--;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000425 Py_DECREF(old_value);
426 Py_DECREF(old_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000427 return 0;
428}
429
Guido van Rossum25831651993-05-19 14:50:45 +0000430void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000431PyDict_Clear(op)
432 PyObject *op;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000433{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000434 int i, n;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000435 register dictentry *table;
436 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000437 if (!PyDict_Check(op))
Guido van Rossum25831651993-05-19 14:50:45 +0000438 return;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000439 mp = (dictobject *)op;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000440 table = mp->ma_table;
441 if (table == NULL)
442 return;
443 n = mp->ma_size;
444 mp->ma_size = mp->ma_used = mp->ma_fill = 0;
445 mp->ma_table = NULL;
446 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000447 Py_XDECREF(table[i].me_key);
448 Py_XDECREF(table[i].me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000449 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000450 PyMem_DEL(table);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000451}
452
Guido van Rossum25831651993-05-19 14:50:45 +0000453int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000454PyDict_Next(op, ppos, pkey, pvalue)
455 PyObject *op;
Guido van Rossum25831651993-05-19 14:50:45 +0000456 int *ppos;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000457 PyObject **pkey;
458 PyObject **pvalue;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000459{
Guido van Rossum25831651993-05-19 14:50:45 +0000460 int i;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000461 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000462 if (!PyDict_Check(op))
Guido van Rossum25831651993-05-19 14:50:45 +0000463 return 0;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000464 mp = (dictobject *)op;
Guido van Rossum25831651993-05-19 14:50:45 +0000465 i = *ppos;
466 if (i < 0)
467 return 0;
468 while (i < mp->ma_size && mp->ma_table[i].me_value == NULL)
469 i++;
470 *ppos = i+1;
471 if (i >= mp->ma_size)
472 return 0;
473 if (pkey)
474 *pkey = mp->ma_table[i].me_key;
475 if (pvalue)
476 *pvalue = mp->ma_table[i].me_value;
477 return 1;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000478}
479
480/* Methods */
481
482static void
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000483dict_dealloc(mp)
484 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000485{
486 register int i;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000487 register dictentry *ep;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000488 for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) {
Guido van Rossum255443b1998-04-10 22:47:14 +0000489 if (ep->me_key != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000490 Py_DECREF(ep->me_key);
Guido van Rossum255443b1998-04-10 22:47:14 +0000491 }
492 if (ep->me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000493 Py_DECREF(ep->me_value);
Guido van Rossum255443b1998-04-10 22:47:14 +0000494 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000495 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000496 PyMem_XDEL(mp->ma_table);
497 PyMem_DEL(mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000498}
499
500static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000501dict_print(mp, fp, flags)
502 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000503 register FILE *fp;
504 register int flags;
505{
506 register int i;
507 register int any;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000508 register dictentry *ep;
Guido van Rossum255443b1998-04-10 22:47:14 +0000509
510 i = Py_ReprEnter((PyObject*)mp);
511 if (i != 0) {
512 if (i < 0)
513 return i;
514 fprintf(fp, "{...}");
515 return 0;
516 }
517
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000518 fprintf(fp, "{");
519 any = 0;
520 for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) {
521 if (ep->me_value != NULL) {
522 if (any++ > 0)
523 fprintf(fp, ", ");
Guido van Rossum255443b1998-04-10 22:47:14 +0000524 if (PyObject_Print((PyObject *)ep->me_key, fp, 0)!=0) {
525 Py_ReprLeave((PyObject*)mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000526 return -1;
Guido van Rossum255443b1998-04-10 22:47:14 +0000527 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000528 fprintf(fp, ": ");
Guido van Rossum255443b1998-04-10 22:47:14 +0000529 if (PyObject_Print(ep->me_value, fp, 0) != 0) {
530 Py_ReprLeave((PyObject*)mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000531 return -1;
Guido van Rossum255443b1998-04-10 22:47:14 +0000532 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000533 }
534 }
535 fprintf(fp, "}");
Guido van Rossum255443b1998-04-10 22:47:14 +0000536 Py_ReprLeave((PyObject*)mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000537 return 0;
538}
539
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000540static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000541dict_repr(mp)
542 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000543{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000544 auto PyObject *v;
545 PyObject *sepa, *colon;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000546 register int i;
547 register int any;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000548 register dictentry *ep;
Guido van Rossum255443b1998-04-10 22:47:14 +0000549
550 i = Py_ReprEnter((PyObject*)mp);
551 if (i != 0) {
552 if (i > 0)
553 return PyString_FromString("{...}");
554 return NULL;
555 }
556
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000557 v = PyString_FromString("{");
558 sepa = PyString_FromString(", ");
559 colon = PyString_FromString(": ");
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000560 any = 0;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000561 for (i = 0, ep = mp->ma_table; i < mp->ma_size && v; i++, ep++) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000562 if (ep->me_value != NULL) {
563 if (any++)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000564 PyString_Concat(&v, sepa);
565 PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_key));
566 PyString_Concat(&v, colon);
567 PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_value));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000568 }
569 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000570 PyString_ConcatAndDel(&v, PyString_FromString("}"));
Guido van Rossum255443b1998-04-10 22:47:14 +0000571 Py_ReprLeave((PyObject*)mp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000572 Py_XDECREF(sepa);
573 Py_XDECREF(colon);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000574 return v;
575}
576
577static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000578dict_length(mp)
579 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000580{
581 return mp->ma_used;
582}
583
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000584static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000585dict_subscript(mp, key)
586 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000587 register PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000588{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000589 PyObject *v;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000590 long hash;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000591 if (mp->ma_table == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000592 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000593 return NULL;
594 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000595#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000596 if (!PyString_Check(key) ||
597 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000598#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000599 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000600 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000601 if (hash == -1)
602 return NULL;
603 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000604 v = lookdict(mp, key, hash) -> me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000605 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000606 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000607 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000608 Py_INCREF(v);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000609 return v;
610}
611
612static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000613dict_ass_sub(mp, v, w)
614 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000615 PyObject *v, *w;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000616{
617 if (w == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000618 return PyDict_DelItem((PyObject *)mp, v);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000619 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000620 return PyDict_SetItem((PyObject *)mp, v, w);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000621}
622
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000623static PyMappingMethods dict_as_mapping = {
624 (inquiry)dict_length, /*mp_length*/
625 (binaryfunc)dict_subscript, /*mp_subscript*/
626 (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000627};
628
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000629static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000630dict_keys(mp, args)
631 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000632 PyObject *args;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000633{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000634 register PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000635 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000636 if (!PyArg_NoArgs(args))
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000637 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000638 v = PyList_New(mp->ma_used);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000639 if (v == NULL)
640 return NULL;
641 for (i = 0, j = 0; i < mp->ma_size; i++) {
642 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000643 PyObject *key = mp->ma_table[i].me_key;
644 Py_INCREF(key);
645 PyList_SetItem(v, j, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000646 j++;
647 }
648 }
649 return v;
650}
651
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000652static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000653dict_values(mp, args)
654 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000655 PyObject *args;
Guido van Rossum25831651993-05-19 14:50:45 +0000656{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000657 register PyObject *v;
Guido van Rossum25831651993-05-19 14:50:45 +0000658 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000659 if (!PyArg_NoArgs(args))
Guido van Rossum25831651993-05-19 14:50:45 +0000660 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000661 v = PyList_New(mp->ma_used);
Guido van Rossum25831651993-05-19 14:50:45 +0000662 if (v == NULL)
663 return NULL;
664 for (i = 0, j = 0; i < mp->ma_size; i++) {
665 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000666 PyObject *value = mp->ma_table[i].me_value;
667 Py_INCREF(value);
668 PyList_SetItem(v, j, value);
Guido van Rossum25831651993-05-19 14:50:45 +0000669 j++;
670 }
671 }
672 return v;
673}
674
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000675static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000676dict_items(mp, args)
677 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000678 PyObject *args;
Guido van Rossum25831651993-05-19 14:50:45 +0000679{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000680 register PyObject *v;
Guido van Rossum25831651993-05-19 14:50:45 +0000681 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000682 if (!PyArg_NoArgs(args))
Guido van Rossum25831651993-05-19 14:50:45 +0000683 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000684 v = PyList_New(mp->ma_used);
Guido van Rossum25831651993-05-19 14:50:45 +0000685 if (v == NULL)
686 return NULL;
687 for (i = 0, j = 0; i < mp->ma_size; i++) {
688 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000689 PyObject *key = mp->ma_table[i].me_key;
690 PyObject *value = mp->ma_table[i].me_value;
691 PyObject *item = PyTuple_New(2);
Guido van Rossum25831651993-05-19 14:50:45 +0000692 if (item == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000693 Py_DECREF(v);
Guido van Rossum25831651993-05-19 14:50:45 +0000694 return NULL;
695 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000696 Py_INCREF(key);
697 PyTuple_SetItem(item, 0, key);
698 Py_INCREF(value);
699 PyTuple_SetItem(item, 1, value);
700 PyList_SetItem(v, j, item);
Guido van Rossum25831651993-05-19 14:50:45 +0000701 j++;
702 }
703 }
704 return v;
705}
706
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000707static PyObject *
Guido van Rossuma8d51311997-06-02 17:13:37 +0000708dict_update(mp, args)
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000709 register dictobject *mp;
710 PyObject *args;
711{
712 register int i;
713 dictobject *other;
714 dictentry *entry;
715 if (!PyArg_Parse(args, "O!", &PyDict_Type, &other))
716 return NULL;
717 if (other == mp)
Guido van Rossuma8d51311997-06-02 17:13:37 +0000718 goto done; /* a.update(a); nothing to do */
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000719 /* Do one big resize at the start, rather than incrementally
720 resizing as we insert new items. Expect that there will be
721 no (or few) overlapping keys. */
722 if ((mp->ma_fill + other->ma_used)*3 >= mp->ma_size*2) {
723 if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0)
724 return NULL;
725 }
726 for (i = 0; i < other->ma_size; i++) {
727 entry = &other->ma_table[i];
728 if (entry->me_value != NULL) {
729 Py_INCREF(entry->me_key);
730 Py_INCREF(entry->me_value);
731 insertdict(mp, entry->me_key, entry->me_hash,
732 entry->me_value);
733 }
734 }
735 done:
736 Py_INCREF(Py_None);
737 return Py_None;
738}
739
740static PyObject *
741dict_copy(mp, args)
742 register dictobject *mp;
743 PyObject *args;
744{
745 register int i;
746 dictobject *copy;
747 dictentry *entry;
748 if (!PyArg_Parse(args, ""))
749 return NULL;
750 copy = (dictobject *)PyDict_New();
751 if (copy == NULL)
752 return NULL;
753 if (mp->ma_used > 0) {
754 if (dictresize(copy, mp->ma_used*3/2) != 0)
755 return NULL;
756 for (i = 0; i < mp->ma_size; i++) {
757 entry = &mp->ma_table[i];
758 if (entry->me_value != NULL) {
759 Py_INCREF(entry->me_key);
760 Py_INCREF(entry->me_value);
761 insertdict(copy, entry->me_key, entry->me_hash,
762 entry->me_value);
763 }
764 }
765 }
766 return (PyObject *)copy;
767}
768
Guido van Rossum4199fac1993-11-05 10:18:44 +0000769int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000770PyDict_Size(mp)
771 PyObject *mp;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000772{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000773 if (mp == NULL || !PyDict_Check(mp)) {
774 PyErr_BadInternalCall();
Guido van Rossumb376a4a1993-11-23 17:53:17 +0000775 return 0;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000776 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000777 return ((dictobject *)mp)->ma_used;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000778}
779
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000780PyObject *
781PyDict_Keys(mp)
782 PyObject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000783{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000784 if (mp == NULL || !PyDict_Check(mp)) {
785 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000786 return NULL;
787 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000788 return dict_keys((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000789}
790
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000791PyObject *
792PyDict_Values(mp)
793 PyObject *mp;
Guido van Rossum25831651993-05-19 14:50:45 +0000794{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000795 if (mp == NULL || !PyDict_Check(mp)) {
796 PyErr_BadInternalCall();
Guido van Rossum25831651993-05-19 14:50:45 +0000797 return NULL;
798 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000799 return dict_values((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum25831651993-05-19 14:50:45 +0000800}
801
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000802PyObject *
803PyDict_Items(mp)
804 PyObject *mp;
Guido van Rossum25831651993-05-19 14:50:45 +0000805{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000806 if (mp == NULL || !PyDict_Check(mp)) {
807 PyErr_BadInternalCall();
Guido van Rossum25831651993-05-19 14:50:45 +0000808 return NULL;
809 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000810 return dict_items((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum25831651993-05-19 14:50:45 +0000811}
812
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000813#define NEWCMP
814
815#ifdef NEWCMP
816
817/* Subroutine which returns the smallest key in a for which b's value
818 is different or absent. The value is returned too, through the
819 pval argument. No reference counts are incremented. */
820
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000821static PyObject *
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000822characterize(a, b, pval)
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000823 dictobject *a;
824 dictobject *b;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000825 PyObject **pval;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000826{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000827 PyObject *diff = NULL;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000828 int i;
829
830 *pval = NULL;
831 for (i = 0; i < a->ma_size; i++) {
832 if (a->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000833 PyObject *key = a->ma_table[i].me_key;
834 PyObject *aval, *bval;
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000835 /* XXX What if PyObject_Compare raises an exception? */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000836 if (diff != NULL && PyObject_Compare(key, diff) > 0)
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000837 continue;
838 aval = a->ma_table[i].me_value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000839 bval = PyDict_GetItem((PyObject *)b, key);
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000840 /* XXX What if PyObject_Compare raises an exception? */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000841 if (bval == NULL || PyObject_Compare(aval, bval) != 0)
842 {
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000843 diff = key;
844 *pval = aval;
845 }
846 }
847 }
848 return diff;
849}
850
851static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000852dict_compare(a, b)
853 dictobject *a, *b;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000854{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000855 PyObject *adiff, *bdiff, *aval, *bval;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000856 int res;
857
858 /* Compare lengths first */
859 if (a->ma_used < b->ma_used)
860 return -1; /* a is shorter */
861 else if (a->ma_used > b->ma_used)
862 return 1; /* b is shorter */
863 /* Same length -- check all keys */
864 adiff = characterize(a, b, &aval);
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000865 if (PyErr_Occurred())
866 return -1;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000867 if (adiff == NULL)
868 return 0; /* a is a subset with the same length */
869 bdiff = characterize(b, a, &bval);
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000870 if (PyErr_Occurred())
871 return -1;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000872 /* bdiff == NULL would be impossible now */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000873 res = PyObject_Compare(adiff, bdiff);
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000874 if (res == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000875 res = PyObject_Compare(aval, bval);
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000876 return res;
877}
878
879#else /* !NEWCMP */
880
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000881static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000882dict_compare(a, b)
883 dictobject *a, *b;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000884{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000885 PyObject *akeys, *bkeys;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000886 int i, n, res;
887 if (a == b)
888 return 0;
889 if (a->ma_used == 0) {
890 if (b->ma_used != 0)
891 return -1;
892 else
893 return 0;
894 }
895 else {
896 if (b->ma_used == 0)
897 return 1;
898 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000899 akeys = dict_keys(a, (PyObject *)NULL);
900 bkeys = dict_keys(b, (PyObject *)NULL);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000901 if (akeys == NULL || bkeys == NULL) {
902 /* Oops, out of memory -- what to do? */
903 /* For now, sort on address! */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000904 Py_XDECREF(akeys);
905 Py_XDECREF(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000906 if (a < b)
907 return -1;
908 else
909 return 1;
910 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000911 PyList_Sort(akeys);
912 PyList_Sort(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000913 n = a->ma_used < b->ma_used ? a->ma_used : b->ma_used; /* smallest */
914 res = 0;
915 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000916 PyObject *akey, *bkey, *aval, *bval;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000917 long ahash, bhash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000918 akey = PyList_GetItem(akeys, i);
919 bkey = PyList_GetItem(bkeys, i);
920 res = PyObject_Compare(akey, bkey);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000921 if (res != 0)
922 break;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000923#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000924 if (!PyString_Check(akey) ||
925 (ahash = ((PyStringObject *) akey)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000926#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000927 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000928 ahash = PyObject_Hash(akey);
Guido van Rossumca756f21997-01-23 19:39:29 +0000929 if (ahash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000930 PyErr_Clear(); /* Don't want errors here */
Guido van Rossumca756f21997-01-23 19:39:29 +0000931 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000932#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000933 if (!PyString_Check(bkey) ||
934 (bhash = ((PyStringObject *) bkey)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000935#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000936 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000937 bhash = PyObject_Hash(bkey);
Guido van Rossumca756f21997-01-23 19:39:29 +0000938 if (bhash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000939 PyErr_Clear(); /* Don't want errors here */
Guido van Rossumca756f21997-01-23 19:39:29 +0000940 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000941 aval = lookdict(a, akey, ahash) -> me_value;
942 bval = lookdict(b, bkey, bhash) -> me_value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000943 res = PyObject_Compare(aval, bval);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000944 if (res != 0)
945 break;
946 }
947 if (res == 0) {
948 if (a->ma_used < b->ma_used)
949 res = -1;
950 else if (a->ma_used > b->ma_used)
951 res = 1;
952 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000953 Py_DECREF(akeys);
954 Py_DECREF(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000955 return res;
956}
957
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000958#endif /* !NEWCMP */
959
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000960static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000961dict_has_key(mp, args)
962 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000963 PyObject *args;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000964{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000965 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000966 long hash;
967 register long ok;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000968 if (!PyArg_Parse(args, "O", &key))
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000969 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000970#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000971 if (!PyString_Check(key) ||
972 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000973#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000974 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000975 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000976 if (hash == -1)
977 return NULL;
978 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000979 ok = mp->ma_size != 0 && lookdict(mp, key, hash)->me_value != NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000980 return PyInt_FromLong(ok);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000981}
982
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000983static PyObject *
Barry Warsawc38c5da1997-10-06 17:49:20 +0000984dict_get(mp, args)
985 register dictobject *mp;
986 PyObject *args;
987{
988 PyObject *key;
Barry Warsaw320ac331997-10-20 17:26:25 +0000989 PyObject *failobj = Py_None;
Barry Warsawc38c5da1997-10-06 17:49:20 +0000990 PyObject *val = NULL;
991 long hash;
992
Barry Warsawc38c5da1997-10-06 17:49:20 +0000993 if (!PyArg_ParseTuple(args, "O|O", &key, &failobj))
994 return NULL;
Guido van Rossum6fcfa721997-10-20 20:10:00 +0000995 if (mp->ma_table == NULL)
996 goto finally;
Barry Warsawc38c5da1997-10-06 17:49:20 +0000997
Barry Warsawc38c5da1997-10-06 17:49:20 +0000998#ifdef CACHE_HASH
999 if (!PyString_Check(key) ||
1000 (hash = ((PyStringObject *) key)->ob_shash) == -1)
1001#endif
1002 {
1003 hash = PyObject_Hash(key);
1004 if (hash == -1)
1005 return NULL;
1006 }
1007 val = lookdict(mp, key, hash)->me_value;
Barry Warsaw320ac331997-10-20 17:26:25 +00001008
Guido van Rossum6fcfa721997-10-20 20:10:00 +00001009 finally:
Barry Warsawc38c5da1997-10-06 17:49:20 +00001010 if (val == NULL)
1011 val = failobj;
1012 Py_INCREF(val);
1013 return val;
1014}
1015
1016
1017static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +00001018dict_clear(mp, args)
1019 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001020 PyObject *args;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +00001021{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001022 if (!PyArg_NoArgs(args))
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +00001023 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001024 PyDict_Clear((PyObject *)mp);
1025 Py_INCREF(Py_None);
1026 return Py_None;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +00001027}
1028
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001029static PyMethodDef mapp_methods[] = {
Guido van Rossum5d8123f1997-07-13 03:58:01 +00001030 {"has_key", (PyCFunction)dict_has_key},
1031 {"keys", (PyCFunction)dict_keys},
1032 {"items", (PyCFunction)dict_items},
1033 {"values", (PyCFunction)dict_values},
Guido van Rossuma8d51311997-06-02 17:13:37 +00001034 {"update", (PyCFunction)dict_update},
Guido van Rossuma9e7a811997-05-13 21:02:11 +00001035 {"clear", (PyCFunction)dict_clear},
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00001036 {"copy", (PyCFunction)dict_copy},
Barry Warsawc38c5da1997-10-06 17:49:20 +00001037 {"get", (PyCFunction)dict_get, 1},
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001038 {NULL, NULL} /* sentinel */
1039};
1040
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001041static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +00001042dict_getattr(mp, name)
1043 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001044 char *name;
1045{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001046 return Py_FindMethod(mapp_methods, (PyObject *)mp, name);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001047}
1048
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001049PyTypeObject PyDict_Type = {
1050 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001051 0,
Guido van Rossum9bfef441993-03-29 10:43:31 +00001052 "dictionary",
Guido van Rossuma9e7a811997-05-13 21:02:11 +00001053 sizeof(dictobject),
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001054 0,
Guido van Rossuma9e7a811997-05-13 21:02:11 +00001055 (destructor)dict_dealloc, /*tp_dealloc*/
1056 (printfunc)dict_print, /*tp_print*/
1057 (getattrfunc)dict_getattr, /*tp_getattr*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001058 0, /*tp_setattr*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +00001059 (cmpfunc)dict_compare, /*tp_compare*/
1060 (reprfunc)dict_repr, /*tp_repr*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001061 0, /*tp_as_number*/
1062 0, /*tp_as_sequence*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +00001063 &dict_as_mapping, /*tp_as_mapping*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001064};
1065
Guido van Rossum3cca2451997-05-16 14:23:33 +00001066/* For backward compatibility with old dictionary interface */
1067
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001068PyObject *
1069PyDict_GetItemString(v, key)
1070 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001071 char *key;
1072{
Guido van Rossum3cca2451997-05-16 14:23:33 +00001073 PyObject *kv, *rv;
1074 kv = PyString_FromString(key);
1075 if (kv == NULL)
1076 return NULL;
Guido van Rossum3cca2451997-05-16 14:23:33 +00001077 rv = PyDict_GetItem(v, kv);
1078 Py_DECREF(kv);
1079 return rv;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001080}
1081
1082int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001083PyDict_SetItemString(v, key, item)
1084 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001085 char *key;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001086 PyObject *item;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001087{
Guido van Rossum3cca2451997-05-16 14:23:33 +00001088 PyObject *kv;
1089 int err;
1090 kv = PyString_FromString(key);
1091 if (kv == NULL)
Guido van Rossum037b2201997-05-20 18:35:19 +00001092 return -1;
Guido van Rossum4f3bf1e1997-09-29 23:31:11 +00001093 PyString_InternInPlace(&kv); /* XXX Should we really? */
Guido van Rossum3cca2451997-05-16 14:23:33 +00001094 err = PyDict_SetItem(v, kv, item);
1095 Py_DECREF(kv);
1096 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001097}
1098
1099int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001100PyDict_DelItemString(v, key)
1101 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001102 char *key;
1103{
Guido van Rossum3cca2451997-05-16 14:23:33 +00001104 PyObject *kv;
1105 int err;
1106 kv = PyString_FromString(key);
1107 if (kv == NULL)
Guido van Rossum037b2201997-05-20 18:35:19 +00001108 return -1;
Guido van Rossum3cca2451997-05-16 14:23:33 +00001109 err = PyDict_DelItem(v, kv);
1110 Py_DECREF(kv);
1111 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001112}