blob: 43d962c2c0e4a0b766b13306e0d855e5e02e2418 [file] [log] [blame]
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum4b1302b1993-03-27 18:11:32 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum4b1302b1993-03-27 18:11:32 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum4b1302b1993-03-27 18:11:32 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum4b1302b1993-03-27 18:11:32 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum4b1302b1993-03-27 18:11:32 +000029
30******************************************************************/
31
Guido van Rossuma9e7a811997-05-13 21:02:11 +000032/* Dictionaru object implementation using a hash table */
Guido van Rossum9bfef441993-03-29 10:43:31 +000033
Guido van Rossumc0b618a1997-05-02 03:12:38 +000034#include "Python.h"
Guido van Rossum4b1302b1993-03-27 18:11:32 +000035
36
37/*
Guido van Rossuma9e7a811997-05-13 21:02:11 +000038 * MINSIZE is the minimum size of a dictionary.
Guido van Rossum16e93a81997-01-28 00:00:11 +000039 */
40
41#define MINSIZE 4
42
43/*
44Table of irreducible polynomials to efficiently cycle through
45GF(2^n)-{0}, 2<=n<=30.
Guido van Rossum4b1302b1993-03-27 18:11:32 +000046*/
Guido van Rossum16e93a81997-01-28 00:00:11 +000047static long polys[] = {
Guido van Rossum9e5656c1997-01-29 04:45:16 +000048 4 + 3,
49 8 + 3,
50 16 + 3,
51 32 + 5,
52 64 + 3,
53 128 + 3,
54 256 + 29,
55 512 + 17,
56 1024 + 9,
57 2048 + 5,
58 4096 + 83,
59 8192 + 27,
60 16384 + 43,
61 32768 + 3,
62 65536 + 45,
63 131072 + 9,
64 262144 + 39,
65 524288 + 39,
66 1048576 + 9,
67 2097152 + 5,
68 4194304 + 3,
69 8388608 + 33,
70 16777216 + 27,
71 33554432 + 9,
72 67108864 + 71,
73 134217728 + 39,
74 268435456 + 9,
75 536870912 + 5,
76 1073741824 + 83,
77 0
Guido van Rossum4b1302b1993-03-27 18:11:32 +000078};
79
80/* Object used as dummy key to fill deleted entries */
Guido van Rossuma9e7a811997-05-13 21:02:11 +000081static PyObject *dummy; /* Initialized by first call to newdictobject() */
Guido van Rossum4b1302b1993-03-27 18:11:32 +000082
83/*
84Invariant for entries: when in use, de_value is not NULL and de_key is
85not NULL and not dummy; when not in use, de_value is NULL and de_key
86is either NULL or dummy. A dummy key value cannot be replaced by
87NULL, since otherwise other keys may be lost.
88*/
89typedef struct {
90 long me_hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091 PyObject *me_key;
92 PyObject *me_value;
Guido van Rossum36488841997-04-11 19:14:07 +000093#ifdef USE_CACHE_ALIGNED
94 long aligner;
95#endif
Guido van Rossuma9e7a811997-05-13 21:02:11 +000096} dictentry;
Guido van Rossum4b1302b1993-03-27 18:11:32 +000097
98/*
99To ensure the lookup algorithm terminates, the table size must be a
100prime number and there must be at least one NULL key in the table.
101The value ma_fill is the number of non-NULL keys; ma_used is the number
102of non-NULL, non-dummy keys.
103To avoid slowing down lookups on a near-full table, we resize the table
104when it is more than half filled.
105*/
106typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000107 PyObject_HEAD
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000108 int ma_fill;
109 int ma_used;
110 int ma_size;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000111 int ma_poly;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000112 dictentry *ma_table;
113} dictobject;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000114
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000115PyObject *
116PyDict_New()
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000117{
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000118 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000119 if (dummy == NULL) { /* Auto-initialize dummy */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000120 dummy = PyString_FromString("<dummy key>");
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000121 if (dummy == NULL)
122 return NULL;
123 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000124 mp = PyObject_NEW(dictobject, &PyDict_Type);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000125 if (mp == NULL)
126 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000127 mp->ma_size = 0;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000128 mp->ma_poly = 0;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000129 mp->ma_table = NULL;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000130 mp->ma_fill = 0;
131 mp->ma_used = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000132 return (PyObject *)mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000133}
134
135/*
136The basic lookup function used by all operations.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000137This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000138Open addressing is preferred over chaining since the link overhead for
139chaining would be substantial (100% with typical malloc overhead).
Guido van Rossum16e93a81997-01-28 00:00:11 +0000140However, instead of going through the table at constant steps, we cycle
141through the values of GF(2^n)-{0}. This avoids modulo computations, being
142much cheaper on RISC machines, without leading to clustering.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000143
144First a 32-bit hash value, 'sum', is computed from the key string.
145The first character is added an extra time shifted by 8 to avoid hashing
146single-character keys (often heavily used variables) too close together.
147All arithmetic on sum should ignore overflow.
148
149The initial probe index is then computed as sum mod the table size.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000150Subsequent probe indices use the values of x^i in GF(2^n) as an offset,
151where x is a root. The initial value is derived from sum, too.
152
153(This version is due to Reimer Behrends, some ideas are also due to
154Jyrki Alakuijala.)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000155*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000156static dictentry *lookdict Py_PROTO((dictobject *, PyObject *, long));
157static dictentry *
158lookdict(mp, key, hash)
159 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000160 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000161 long hash;
162{
Guido van Rossum16e93a81997-01-28 00:00:11 +0000163 register int i;
164 register unsigned incr;
165 register unsigned long sum = (unsigned long) hash;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000166 register dictentry *freeslot = NULL;
Guido van Rossum2095d241997-04-09 19:41:24 +0000167 register unsigned int mask = mp->ma_size-1;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000168 dictentry *ep0 = mp->ma_table;
169 register dictentry *ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000170 /* We must come up with (i, incr) such that 0 <= i < ma_size
171 and 0 < incr < ma_size and both are a function of hash */
172 i = (~sum) & mask;
173 /* We use ~sum instead if sum, as degenerate hash functions, such
174 as for ints <sigh>, can have lots of leading zeros. It's not
175 really a performance risk, but better safe than sorry. */
Guido van Rossumefb46091997-01-29 15:53:56 +0000176 ep = &ep0[i];
Guido van Rossum16e93a81997-01-28 00:00:11 +0000177 if (ep->me_key == NULL)
Guido van Rossum7d181591997-01-16 21:06:45 +0000178 return ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000179 if (ep->me_key == dummy)
Guido van Rossum7d181591997-01-16 21:06:45 +0000180 freeslot = ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000181 else if (ep->me_key == key ||
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000182 (ep->me_hash == hash &&
183 PyObject_Compare(ep->me_key, key) == 0))
184 {
Guido van Rossum16e93a81997-01-28 00:00:11 +0000185 return ep;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000186 }
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000187 /* XXX What if PyObject_Compare returned an exception? */
Guido van Rossumefb46091997-01-29 15:53:56 +0000188 /* Derive incr from sum, just to make it more arbitrary. Note that
Guido van Rossum16e93a81997-01-28 00:00:11 +0000189 incr must not be 0, or we will get into an infinite loop.*/
Guido van Rossumefb46091997-01-29 15:53:56 +0000190 incr = (sum ^ (sum >> 3)) & mask;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000191 if (!incr)
192 incr = mask;
193 if (incr > mask) /* Cycle through GF(2^n)-{0} */
194 incr ^= mp->ma_poly; /* This will implicitly clear the
195 highest bit */
196 for (;;) {
Guido van Rossumefb46091997-01-29 15:53:56 +0000197 ep = &ep0[(i+incr)&mask];
Guido van Rossum16e93a81997-01-28 00:00:11 +0000198 if (ep->me_key == NULL) {
199 if (freeslot != NULL)
200 return freeslot;
201 else
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000202 return ep;
203 }
Guido van Rossum16e93a81997-01-28 00:00:11 +0000204 if (ep->me_key == dummy) {
205 if (freeslot == NULL)
206 freeslot = ep;
207 }
208 else if (ep->me_key == key ||
209 (ep->me_hash == hash &&
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000210 PyObject_Compare(ep->me_key, key) == 0)) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000211 return ep;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000212 }
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000213 /* XXX What if PyObject_Compare returned an exception? */
Guido van Rossum16e93a81997-01-28 00:00:11 +0000214 /* Cycle through GF(2^n)-{0} */
215 incr = incr << 1;
216 if (incr > mask)
217 incr ^= mp->ma_poly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000218 }
219}
220
221/*
222Internal routine to insert a new item into the table.
223Used both by the internal resize routine and by the public insert routine.
224Eats a reference to key and one to value.
225*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000226static void insertdict
227 Py_PROTO((dictobject *, PyObject *, long, PyObject *));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000228static void
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000229insertdict(mp, key, hash, value)
230 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000232 long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 PyObject *value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000234{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235 PyObject *old_value;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000236 register dictentry *ep;
237 ep = lookdict(mp, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000238 if (ep->me_value != NULL) {
Guido van Rossumd7047b31995-01-02 19:07:15 +0000239 old_value = ep->me_value;
240 ep->me_value = value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000241 Py_DECREF(old_value); /* which **CAN** re-enter */
242 Py_DECREF(key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000243 }
244 else {
245 if (ep->me_key == NULL)
246 mp->ma_fill++;
247 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000248 Py_DECREF(ep->me_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000249 ep->me_key = key;
250 ep->me_hash = hash;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000251 ep->me_value = value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000252 mp->ma_used++;
253 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000254}
255
256/*
257Restructure the table by allocating a new table and reinserting all
258items again. When entries have been deleted, the new table may
259actually be smaller than the old one.
260*/
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000261static int dictresize Py_PROTO((dictobject *, int));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000262static int
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000263dictresize(mp, minused)
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000264 dictobject *mp;
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000265 int minused;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000266{
267 register int oldsize = mp->ma_size;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000268 register int newsize, newpoly;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000269 register dictentry *oldtable = mp->ma_table;
270 register dictentry *newtable;
271 register dictentry *ep;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000272 register int i;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000273 for (i = 0, newsize = MINSIZE; ; i++, newsize <<= 1) {
274 if (i > sizeof(polys)/sizeof(polys[0])) {
275 /* Ran out of polynomials */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000276 PyErr_NoMemory();
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000277 return -1;
278 }
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000279 if (newsize > minused) {
Guido van Rossum16e93a81997-01-28 00:00:11 +0000280 newpoly = polys[i];
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000281 break;
282 }
283 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000284 newtable = (dictentry *) calloc(sizeof(dictentry), newsize);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000285 if (newtable == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000286 PyErr_NoMemory();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000287 return -1;
288 }
289 mp->ma_size = newsize;
Guido van Rossum16e93a81997-01-28 00:00:11 +0000290 mp->ma_poly = newpoly;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000291 mp->ma_table = newtable;
292 mp->ma_fill = 0;
293 mp->ma_used = 0;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000294
295 /* Make two passes, so we can avoid decrefs
296 (and possible side effects) till the table is copied */
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000297 for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
298 if (ep->me_value != NULL)
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000299 insertdict(mp,ep->me_key,ep->me_hash,ep->me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000300 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000301 for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
302 if (ep->me_value == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000303 Py_XDECREF(ep->me_key);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000304 }
305
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306 PyMem_XDEL(oldtable);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000307 return 0;
308}
309
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310PyObject *
311PyDict_GetItem(op, key)
312 PyObject *op;
313 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000314{
315 long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000316 if (!PyDict_Check(op)) {
317 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000318 return NULL;
319 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000320 if (((dictobject *)op)->ma_table == NULL)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000321 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000322#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000323 if (!PyString_Check(key) ||
324 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000325#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000326 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000327 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000328 if (hash == -1)
329 return NULL;
330 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000331 return lookdict((dictobject *)op, key, hash) -> me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000332}
333
334int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000335PyDict_SetItem(op, key, value)
336 register PyObject *op;
337 PyObject *key;
338 PyObject *value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000339{
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000340 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000341 register long hash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000342 if (!PyDict_Check(op)) {
343 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000344 return -1;
345 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000346 mp = (dictobject *)op;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000347#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000348 if (PyString_Check(key)) {
Guido van Rossum2a61e741997-01-18 07:55:05 +0000349#ifdef INTERN_STRINGS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000350 if (((PyStringObject *)key)->ob_sinterned != NULL) {
351 key = ((PyStringObject *)key)->ob_sinterned;
352 hash = ((PyStringObject *)key)->ob_shash;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000353 }
354 else
355#endif
356 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000357 hash = ((PyStringObject *)key)->ob_shash;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000358 if (hash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000359 hash = PyObject_Hash(key);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000360 }
361 }
362 else
363#endif
364 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000365 hash = PyObject_Hash(key);
Guido van Rossum2a61e741997-01-18 07:55:05 +0000366 if (hash == -1)
367 return -1;
Guido van Rossum2a61e741997-01-18 07:55:05 +0000368 }
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000369 /* if fill >= 2/3 size, double in size */
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000370 if (mp->ma_fill*3 >= mp->ma_size*2) {
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000371 if (dictresize(mp, mp->ma_used*2) != 0) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000372 if (mp->ma_fill+1 > mp->ma_size)
373 return -1;
374 }
375 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000376 Py_INCREF(value);
377 Py_INCREF(key);
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000378 insertdict(mp, key, hash, value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000379 return 0;
380}
381
382int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000383PyDict_DelItem(op, key)
384 PyObject *op;
385 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000386{
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000387 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000388 register long hash;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000389 register dictentry *ep;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390 PyObject *old_value, *old_key;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000391
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 if (!PyDict_Check(op)) {
393 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000394 return -1;
395 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000396#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000397 if (!PyString_Check(key) ||
398 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000399#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000400 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000401 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000402 if (hash == -1)
403 return -1;
404 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000405 mp = (dictobject *)op;
406 if (((dictobject *)op)->ma_table == NULL)
Guido van Rossumefc87131995-01-02 19:42:39 +0000407 goto empty;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000408 ep = lookdict(mp, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000409 if (ep->me_value == NULL) {
Guido van Rossumefc87131995-01-02 19:42:39 +0000410 empty:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000411 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000412 return -1;
413 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000414 old_key = ep->me_key;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000415 Py_INCREF(dummy);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000416 ep->me_key = dummy;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000417 old_value = ep->me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000418 ep->me_value = NULL;
419 mp->ma_used--;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000420 Py_DECREF(old_value);
421 Py_DECREF(old_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000422 return 0;
423}
424
Guido van Rossum25831651993-05-19 14:50:45 +0000425void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000426PyDict_Clear(op)
427 PyObject *op;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000428{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000429 int i, n;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000430 register dictentry *table;
431 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432 if (!PyDict_Check(op))
Guido van Rossum25831651993-05-19 14:50:45 +0000433 return;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000434 mp = (dictobject *)op;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000435 table = mp->ma_table;
436 if (table == NULL)
437 return;
438 n = mp->ma_size;
439 mp->ma_size = mp->ma_used = mp->ma_fill = 0;
440 mp->ma_table = NULL;
441 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000442 Py_XDECREF(table[i].me_key);
443 Py_XDECREF(table[i].me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000444 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000445 PyMem_DEL(table);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000446}
447
Guido van Rossum25831651993-05-19 14:50:45 +0000448int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000449PyDict_Next(op, ppos, pkey, pvalue)
450 PyObject *op;
Guido van Rossum25831651993-05-19 14:50:45 +0000451 int *ppos;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000452 PyObject **pkey;
453 PyObject **pvalue;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000454{
Guido van Rossum25831651993-05-19 14:50:45 +0000455 int i;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000456 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000457 if (!PyDict_Check(op))
Guido van Rossum25831651993-05-19 14:50:45 +0000458 return 0;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000459 mp = (dictobject *)op;
Guido van Rossum25831651993-05-19 14:50:45 +0000460 i = *ppos;
461 if (i < 0)
462 return 0;
463 while (i < mp->ma_size && mp->ma_table[i].me_value == NULL)
464 i++;
465 *ppos = i+1;
466 if (i >= mp->ma_size)
467 return 0;
468 if (pkey)
469 *pkey = mp->ma_table[i].me_key;
470 if (pvalue)
471 *pvalue = mp->ma_table[i].me_value;
472 return 1;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000473}
474
475/* Methods */
476
477static void
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000478dict_dealloc(mp)
479 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000480{
481 register int i;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000482 register dictentry *ep;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000483 for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) {
484 if (ep->me_key != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000485 Py_DECREF(ep->me_key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000486 if (ep->me_value != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000487 Py_DECREF(ep->me_value);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000488 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489 PyMem_XDEL(mp->ma_table);
490 PyMem_DEL(mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000491}
492
493static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000494dict_print(mp, fp, flags)
495 register dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000496 register FILE *fp;
497 register int flags;
498{
499 register int i;
500 register int any;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000501 register dictentry *ep;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000502 fprintf(fp, "{");
503 any = 0;
504 for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) {
505 if (ep->me_value != NULL) {
506 if (any++ > 0)
507 fprintf(fp, ", ");
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000508 if (PyObject_Print((PyObject *)ep->me_key, fp, 0) != 0)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000509 return -1;
510 fprintf(fp, ": ");
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000511 if (PyObject_Print(ep->me_value, fp, 0) != 0)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000512 return -1;
513 }
514 }
515 fprintf(fp, "}");
516 return 0;
517}
518
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000519static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000520dict_repr(mp)
521 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000522{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523 auto PyObject *v;
524 PyObject *sepa, *colon;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000525 register int i;
526 register int any;
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000527 register dictentry *ep;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000528 v = PyString_FromString("{");
529 sepa = PyString_FromString(", ");
530 colon = PyString_FromString(": ");
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000531 any = 0;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000532 for (i = 0, ep = mp->ma_table; i < mp->ma_size && v; i++, ep++) {
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000533 if (ep->me_value != NULL) {
534 if (any++)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000535 PyString_Concat(&v, sepa);
536 PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_key));
537 PyString_Concat(&v, colon);
538 PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_value));
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000539 }
540 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000541 PyString_ConcatAndDel(&v, PyString_FromString("}"));
542 Py_XDECREF(sepa);
543 Py_XDECREF(colon);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000544 return v;
545}
546
547static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000548dict_length(mp)
549 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000550{
551 return mp->ma_used;
552}
553
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000554static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000555dict_subscript(mp, key)
556 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000557 register PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000558{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559 PyObject *v;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000560 long hash;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000561 if (mp->ma_table == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000562 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000563 return NULL;
564 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000565#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000566 if (!PyString_Check(key) ||
567 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000568#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000569 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000570 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000571 if (hash == -1)
572 return NULL;
573 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000574 v = lookdict(mp, key, hash) -> me_value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000575 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000576 PyErr_SetObject(PyExc_KeyError, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000577 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000578 Py_INCREF(v);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000579 return v;
580}
581
582static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000583dict_ass_sub(mp, v, w)
584 dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000585 PyObject *v, *w;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000586{
587 if (w == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000588 return PyDict_DelItem((PyObject *)mp, v);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000589 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000590 return PyDict_SetItem((PyObject *)mp, v, w);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000591}
592
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000593static PyMappingMethods dict_as_mapping = {
594 (inquiry)dict_length, /*mp_length*/
595 (binaryfunc)dict_subscript, /*mp_subscript*/
596 (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000597};
598
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000599static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000600dict_keys(mp, args)
601 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000602 PyObject *args;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000603{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604 register PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000605 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000606 if (!PyArg_NoArgs(args))
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000607 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000608 v = PyList_New(mp->ma_used);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000609 if (v == NULL)
610 return NULL;
611 for (i = 0, j = 0; i < mp->ma_size; i++) {
612 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000613 PyObject *key = mp->ma_table[i].me_key;
614 Py_INCREF(key);
615 PyList_SetItem(v, j, key);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000616 j++;
617 }
618 }
619 return v;
620}
621
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000622static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000623dict_values(mp, args)
624 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 PyObject *args;
Guido van Rossum25831651993-05-19 14:50:45 +0000626{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 register PyObject *v;
Guido van Rossum25831651993-05-19 14:50:45 +0000628 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000629 if (!PyArg_NoArgs(args))
Guido van Rossum25831651993-05-19 14:50:45 +0000630 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000631 v = PyList_New(mp->ma_used);
Guido van Rossum25831651993-05-19 14:50:45 +0000632 if (v == NULL)
633 return NULL;
634 for (i = 0, j = 0; i < mp->ma_size; i++) {
635 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000636 PyObject *value = mp->ma_table[i].me_value;
637 Py_INCREF(value);
638 PyList_SetItem(v, j, value);
Guido van Rossum25831651993-05-19 14:50:45 +0000639 j++;
640 }
641 }
642 return v;
643}
644
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000645static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000646dict_items(mp, args)
647 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000648 PyObject *args;
Guido van Rossum25831651993-05-19 14:50:45 +0000649{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000650 register PyObject *v;
Guido van Rossum25831651993-05-19 14:50:45 +0000651 register int i, j;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000652 if (!PyArg_NoArgs(args))
Guido van Rossum25831651993-05-19 14:50:45 +0000653 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654 v = PyList_New(mp->ma_used);
Guido van Rossum25831651993-05-19 14:50:45 +0000655 if (v == NULL)
656 return NULL;
657 for (i = 0, j = 0; i < mp->ma_size; i++) {
658 if (mp->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000659 PyObject *key = mp->ma_table[i].me_key;
660 PyObject *value = mp->ma_table[i].me_value;
661 PyObject *item = PyTuple_New(2);
Guido van Rossum25831651993-05-19 14:50:45 +0000662 if (item == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000663 Py_DECREF(v);
Guido van Rossum25831651993-05-19 14:50:45 +0000664 return NULL;
665 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000666 Py_INCREF(key);
667 PyTuple_SetItem(item, 0, key);
668 Py_INCREF(value);
669 PyTuple_SetItem(item, 1, value);
670 PyList_SetItem(v, j, item);
Guido van Rossum25831651993-05-19 14:50:45 +0000671 j++;
672 }
673 }
674 return v;
675}
676
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000677static PyObject *
Guido van Rossuma8d51311997-06-02 17:13:37 +0000678dict_update(mp, args)
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000679 register dictobject *mp;
680 PyObject *args;
681{
682 register int i;
683 dictobject *other;
684 dictentry *entry;
685 if (!PyArg_Parse(args, "O!", &PyDict_Type, &other))
686 return NULL;
687 if (other == mp)
Guido van Rossuma8d51311997-06-02 17:13:37 +0000688 goto done; /* a.update(a); nothing to do */
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000689 /* Do one big resize at the start, rather than incrementally
690 resizing as we insert new items. Expect that there will be
691 no (or few) overlapping keys. */
692 if ((mp->ma_fill + other->ma_used)*3 >= mp->ma_size*2) {
693 if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0)
694 return NULL;
695 }
696 for (i = 0; i < other->ma_size; i++) {
697 entry = &other->ma_table[i];
698 if (entry->me_value != NULL) {
699 Py_INCREF(entry->me_key);
700 Py_INCREF(entry->me_value);
701 insertdict(mp, entry->me_key, entry->me_hash,
702 entry->me_value);
703 }
704 }
705 done:
706 Py_INCREF(Py_None);
707 return Py_None;
708}
709
710static PyObject *
711dict_copy(mp, args)
712 register dictobject *mp;
713 PyObject *args;
714{
715 register int i;
716 dictobject *copy;
717 dictentry *entry;
718 if (!PyArg_Parse(args, ""))
719 return NULL;
720 copy = (dictobject *)PyDict_New();
721 if (copy == NULL)
722 return NULL;
723 if (mp->ma_used > 0) {
724 if (dictresize(copy, mp->ma_used*3/2) != 0)
725 return NULL;
726 for (i = 0; i < mp->ma_size; i++) {
727 entry = &mp->ma_table[i];
728 if (entry->me_value != NULL) {
729 Py_INCREF(entry->me_key);
730 Py_INCREF(entry->me_value);
731 insertdict(copy, entry->me_key, entry->me_hash,
732 entry->me_value);
733 }
734 }
735 }
736 return (PyObject *)copy;
737}
738
Guido van Rossum4199fac1993-11-05 10:18:44 +0000739int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000740PyDict_Size(mp)
741 PyObject *mp;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000742{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000743 if (mp == NULL || !PyDict_Check(mp)) {
744 PyErr_BadInternalCall();
Guido van Rossumb376a4a1993-11-23 17:53:17 +0000745 return 0;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000746 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000747 return ((dictobject *)mp)->ma_used;
Guido van Rossum4199fac1993-11-05 10:18:44 +0000748}
749
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000750PyObject *
751PyDict_Keys(mp)
752 PyObject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000753{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000754 if (mp == NULL || !PyDict_Check(mp)) {
755 PyErr_BadInternalCall();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000756 return NULL;
757 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000758 return dict_keys((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000759}
760
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000761PyObject *
762PyDict_Values(mp)
763 PyObject *mp;
Guido van Rossum25831651993-05-19 14:50:45 +0000764{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000765 if (mp == NULL || !PyDict_Check(mp)) {
766 PyErr_BadInternalCall();
Guido van Rossum25831651993-05-19 14:50:45 +0000767 return NULL;
768 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000769 return dict_values((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum25831651993-05-19 14:50:45 +0000770}
771
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000772PyObject *
773PyDict_Items(mp)
774 PyObject *mp;
Guido van Rossum25831651993-05-19 14:50:45 +0000775{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000776 if (mp == NULL || !PyDict_Check(mp)) {
777 PyErr_BadInternalCall();
Guido van Rossum25831651993-05-19 14:50:45 +0000778 return NULL;
779 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000780 return dict_items((dictobject *)mp, (PyObject *)NULL);
Guido van Rossum25831651993-05-19 14:50:45 +0000781}
782
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000783#define NEWCMP
784
785#ifdef NEWCMP
786
787/* Subroutine which returns the smallest key in a for which b's value
788 is different or absent. The value is returned too, through the
789 pval argument. No reference counts are incremented. */
790
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000791static PyObject *
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000792characterize(a, b, pval)
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000793 dictobject *a;
794 dictobject *b;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000795 PyObject **pval;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000796{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000797 PyObject *diff = NULL;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000798 int i;
799
800 *pval = NULL;
801 for (i = 0; i < a->ma_size; i++) {
802 if (a->ma_table[i].me_value != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000803 PyObject *key = a->ma_table[i].me_key;
804 PyObject *aval, *bval;
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000805 /* XXX What if PyObject_Compare raises an exception? */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000806 if (diff != NULL && PyObject_Compare(key, diff) > 0)
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000807 continue;
808 aval = a->ma_table[i].me_value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000809 bval = PyDict_GetItem((PyObject *)b, key);
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000810 /* XXX What if PyObject_Compare raises an exception? */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000811 if (bval == NULL || PyObject_Compare(aval, bval) != 0)
812 {
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000813 diff = key;
814 *pval = aval;
815 }
816 }
817 }
818 return diff;
819}
820
821static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000822dict_compare(a, b)
823 dictobject *a, *b;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000824{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000825 PyObject *adiff, *bdiff, *aval, *bval;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000826 int res;
827
828 /* Compare lengths first */
829 if (a->ma_used < b->ma_used)
830 return -1; /* a is shorter */
831 else if (a->ma_used > b->ma_used)
832 return 1; /* b is shorter */
833 /* Same length -- check all keys */
834 adiff = characterize(a, b, &aval);
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000835 if (PyErr_Occurred())
836 return -1;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000837 if (adiff == NULL)
838 return 0; /* a is a subset with the same length */
839 bdiff = characterize(b, a, &bval);
Guido van Rossum5b2121b1997-05-23 00:01:41 +0000840 if (PyErr_Occurred())
841 return -1;
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000842 /* bdiff == NULL would be impossible now */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000843 res = PyObject_Compare(adiff, bdiff);
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000844 if (res == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000845 res = PyObject_Compare(aval, bval);
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000846 return res;
847}
848
849#else /* !NEWCMP */
850
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000851static int
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000852dict_compare(a, b)
853 dictobject *a, *b;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000854{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000855 PyObject *akeys, *bkeys;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000856 int i, n, res;
857 if (a == b)
858 return 0;
859 if (a->ma_used == 0) {
860 if (b->ma_used != 0)
861 return -1;
862 else
863 return 0;
864 }
865 else {
866 if (b->ma_used == 0)
867 return 1;
868 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000869 akeys = dict_keys(a, (PyObject *)NULL);
870 bkeys = dict_keys(b, (PyObject *)NULL);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000871 if (akeys == NULL || bkeys == NULL) {
872 /* Oops, out of memory -- what to do? */
873 /* For now, sort on address! */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000874 Py_XDECREF(akeys);
875 Py_XDECREF(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000876 if (a < b)
877 return -1;
878 else
879 return 1;
880 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000881 PyList_Sort(akeys);
882 PyList_Sort(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000883 n = a->ma_used < b->ma_used ? a->ma_used : b->ma_used; /* smallest */
884 res = 0;
885 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000886 PyObject *akey, *bkey, *aval, *bval;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000887 long ahash, bhash;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000888 akey = PyList_GetItem(akeys, i);
889 bkey = PyList_GetItem(bkeys, i);
890 res = PyObject_Compare(akey, bkey);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000891 if (res != 0)
892 break;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000893#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000894 if (!PyString_Check(akey) ||
895 (ahash = ((PyStringObject *) akey)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000896#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000897 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000898 ahash = PyObject_Hash(akey);
Guido van Rossumca756f21997-01-23 19:39:29 +0000899 if (ahash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000900 PyErr_Clear(); /* Don't want errors here */
Guido van Rossumca756f21997-01-23 19:39:29 +0000901 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000902#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903 if (!PyString_Check(bkey) ||
904 (bhash = ((PyStringObject *) bkey)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000905#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000906 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000907 bhash = PyObject_Hash(bkey);
Guido van Rossumca756f21997-01-23 19:39:29 +0000908 if (bhash == -1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000909 PyErr_Clear(); /* Don't want errors here */
Guido van Rossumca756f21997-01-23 19:39:29 +0000910 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000911 aval = lookdict(a, akey, ahash) -> me_value;
912 bval = lookdict(b, bkey, bhash) -> me_value;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000913 res = PyObject_Compare(aval, bval);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000914 if (res != 0)
915 break;
916 }
917 if (res == 0) {
918 if (a->ma_used < b->ma_used)
919 res = -1;
920 else if (a->ma_used > b->ma_used)
921 res = 1;
922 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000923 Py_DECREF(akeys);
924 Py_DECREF(bkeys);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000925 return res;
926}
927
Guido van Rossuma0a69b81996-12-05 21:55:55 +0000928#endif /* !NEWCMP */
929
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000930static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000931dict_has_key(mp, args)
932 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000933 PyObject *args;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000934{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000935 PyObject *key;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000936 long hash;
937 register long ok;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000938 if (!PyArg_Parse(args, "O", &key))
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000939 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000940#ifdef CACHE_HASH
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000941 if (!PyString_Check(key) ||
942 (hash = ((PyStringObject *) key)->ob_shash) == -1)
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000943#endif
Guido van Rossumca756f21997-01-23 19:39:29 +0000944 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000945 hash = PyObject_Hash(key);
Guido van Rossumca756f21997-01-23 19:39:29 +0000946 if (hash == -1)
947 return NULL;
948 }
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000949 ok = mp->ma_size != 0 && lookdict(mp, key, hash)->me_value != NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000950 return PyInt_FromLong(ok);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000951}
952
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000953static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000954dict_clear(mp, args)
955 register dictobject *mp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000956 PyObject *args;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000957{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000958 if (!PyArg_NoArgs(args))
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000959 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000960 PyDict_Clear((PyObject *)mp);
961 Py_INCREF(Py_None);
962 return Py_None;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +0000963}
964
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000965static PyMethodDef mapp_methods[] = {
Guido van Rossuma8d51311997-06-02 17:13:37 +0000966 {"update", (PyCFunction)dict_update},
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000967 {"clear", (PyCFunction)dict_clear},
Guido van Rossume3f5b9c1997-05-28 19:15:28 +0000968 {"copy", (PyCFunction)dict_copy},
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000969 {"has_key", (PyCFunction)dict_has_key},
970 {"items", (PyCFunction)dict_items},
971 {"keys", (PyCFunction)dict_keys},
972 {"values", (PyCFunction)dict_values},
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000973 {NULL, NULL} /* sentinel */
974};
975
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000976static PyObject *
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000977dict_getattr(mp, name)
978 dictobject *mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000979 char *name;
980{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000981 return Py_FindMethod(mapp_methods, (PyObject *)mp, name);
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000982}
983
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000984PyTypeObject PyDict_Type = {
985 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000986 0,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000987 "dictionary",
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000988 sizeof(dictobject),
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000989 0,
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000990 (destructor)dict_dealloc, /*tp_dealloc*/
991 (printfunc)dict_print, /*tp_print*/
992 (getattrfunc)dict_getattr, /*tp_getattr*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000993 0, /*tp_setattr*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000994 (cmpfunc)dict_compare, /*tp_compare*/
995 (reprfunc)dict_repr, /*tp_repr*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000996 0, /*tp_as_number*/
997 0, /*tp_as_sequence*/
Guido van Rossuma9e7a811997-05-13 21:02:11 +0000998 &dict_as_mapping, /*tp_as_mapping*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000999};
1000
Guido van Rossum3cca2451997-05-16 14:23:33 +00001001/* For backward compatibility with old dictionary interface */
1002
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001003PyObject *
1004PyDict_GetItemString(v, key)
1005 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001006 char *key;
1007{
Guido van Rossum3cca2451997-05-16 14:23:33 +00001008 PyObject *kv, *rv;
1009 kv = PyString_FromString(key);
1010 if (kv == NULL)
1011 return NULL;
1012 PyString_InternInPlace(&kv);
1013 rv = PyDict_GetItem(v, kv);
1014 Py_DECREF(kv);
1015 return rv;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001016}
1017
1018int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001019PyDict_SetItemString(v, key, item)
1020 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001021 char *key;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001022 PyObject *item;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001023{
Guido van Rossum3cca2451997-05-16 14:23:33 +00001024 PyObject *kv;
1025 int err;
1026 kv = PyString_FromString(key);
1027 if (kv == NULL)
Guido van Rossum037b2201997-05-20 18:35:19 +00001028 return -1;
Guido van Rossum3cca2451997-05-16 14:23:33 +00001029 PyString_InternInPlace(&kv);
1030 err = PyDict_SetItem(v, kv, item);
1031 Py_DECREF(kv);
1032 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001033}
1034
1035int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001036PyDict_DelItemString(v, key)
1037 PyObject *v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001038 char *key;
1039{
Guido van Rossum3cca2451997-05-16 14:23:33 +00001040 PyObject *kv;
1041 int err;
1042 kv = PyString_FromString(key);
1043 if (kv == NULL)
Guido van Rossum037b2201997-05-20 18:35:19 +00001044 return -1;
Guido van Rossum3cca2451997-05-16 14:23:33 +00001045 PyString_InternInPlace(&kv);
1046 err = PyDict_DelItem(v, kv);
1047 Py_DECREF(kv);
1048 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001049}