| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1 |  | 
| Guido van Rossum | 2bc1379 | 1999-03-24 19:06:42 +0000 | [diff] [blame] | 2 | /* Dictionary object implementation using a hash table */ | 
| Guido van Rossum | 9bfef44 | 1993-03-29 10:43:31 +0000 | [diff] [blame] | 3 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 4 | #include "Python.h" | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 5 |  | 
 | 6 |  | 
 | 7 | /* | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 8 |  * MINSIZE is the minimum size of a dictionary. | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 9 |  */ | 
 | 10 |  | 
 | 11 | #define MINSIZE 4 | 
 | 12 |  | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 13 | /* define this out if you don't want conversion statistics on exit */ | 
 | 14 | #undef SHOW_CONVERSION_COUNTS | 
 | 15 |  | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 16 | /* | 
 | 17 | Table of irreducible polynomials to efficiently cycle through | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 18 | GF(2^n)-{0}, 2<=n<=30.  A table size is always a power of 2. | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 19 | */ | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 20 | static long polys[] = { | 
| Guido van Rossum | 9e5656c | 1997-01-29 04:45:16 +0000 | [diff] [blame] | 21 | 	4 + 3, | 
 | 22 | 	8 + 3, | 
 | 23 | 	16 + 3, | 
 | 24 | 	32 + 5, | 
 | 25 | 	64 + 3, | 
 | 26 | 	128 + 3, | 
 | 27 | 	256 + 29, | 
 | 28 | 	512 + 17, | 
 | 29 | 	1024 + 9, | 
 | 30 | 	2048 + 5, | 
 | 31 | 	4096 + 83, | 
 | 32 | 	8192 + 27, | 
 | 33 | 	16384 + 43, | 
 | 34 | 	32768 + 3, | 
 | 35 | 	65536 + 45, | 
 | 36 | 	131072 + 9, | 
 | 37 | 	262144 + 39, | 
 | 38 | 	524288 + 39, | 
 | 39 | 	1048576 + 9, | 
 | 40 | 	2097152 + 5, | 
 | 41 | 	4194304 + 3, | 
 | 42 | 	8388608 + 33, | 
 | 43 | 	16777216 + 27, | 
 | 44 | 	33554432 + 9, | 
 | 45 | 	67108864 + 71, | 
 | 46 | 	134217728 + 39, | 
 | 47 | 	268435456 + 9, | 
 | 48 | 	536870912 + 5, | 
 | 49 | 	1073741824 + 83, | 
 | 50 | 	0 | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 51 | }; | 
 | 52 |  | 
 | 53 | /* Object used as dummy key to fill deleted entries */ | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 54 | static PyObject *dummy; /* Initialized by first call to newdictobject() */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 55 |  | 
 | 56 | /* | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 57 | There are three kinds of slots in the table: | 
 | 58 |  | 
 | 59 | 1. Unused.  me_key == me_value == NULL | 
 | 60 |    Does not hold an active (key, value) pair now and never did.  Unused can | 
 | 61 |    transition to Active upon key insertion.  This is the only case in which | 
 | 62 |    me_key is NULL, and is each slot's initial state. | 
 | 63 |  | 
 | 64 | 2. Active.  me_key != NULL and me_key != dummy and me_value != NULL | 
 | 65 |    Holds an active (key, value) pair.  Active can transition to Dummy upon | 
 | 66 |    key deletion.  This is the only case in which me_value != NULL. | 
 | 67 |  | 
| Tim Peters | f1c7c88 | 2000-12-13 19:58:25 +0000 | [diff] [blame] | 68 | 3. Dummy.  me_key == dummy and me_value == NULL | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 69 |    Previously held an active (key, value) pair, but that was deleted and an | 
 | 70 |    active pair has not yet overwritten the slot.  Dummy can transition to | 
 | 71 |    Active upon key insertion.  Dummy slots cannot be made Unused again | 
 | 72 |    (cannot have me_key set to NULL), else the probe sequence in case of | 
 | 73 |    collision would have no way to know they were once active. | 
| Tim Peters | f1c7c88 | 2000-12-13 19:58:25 +0000 | [diff] [blame] | 74 |  | 
 | 75 | Note: .popitem() abuses the me_hash field of an Unused or Dummy slot to | 
 | 76 | hold a search finger.  The me_hash field of Unused or Dummy slots has no | 
 | 77 | meaning otherwise. | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 78 | */ | 
 | 79 | typedef struct { | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 80 | 	long me_hash;      /* cached hash code of me_key */ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 81 | 	PyObject *me_key; | 
 | 82 | 	PyObject *me_value; | 
| Guido van Rossum | 3648884 | 1997-04-11 19:14:07 +0000 | [diff] [blame] | 83 | #ifdef USE_CACHE_ALIGNED | 
 | 84 | 	long	aligner; | 
 | 85 | #endif | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 86 | } dictentry; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 87 |  | 
 | 88 | /* | 
| Tim Peters | f1c7c88 | 2000-12-13 19:58:25 +0000 | [diff] [blame] | 89 | To ensure the lookup algorithm terminates, there must be at least one Unused | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 90 | slot (NULL key) in the table. | 
 | 91 | The value ma_fill is the number of non-NULL keys (sum of Active and Dummy); | 
 | 92 | ma_used is the number of non-NULL, non-dummy keys (== the number of non-NULL | 
 | 93 | values == the number of Active items). | 
 | 94 | To avoid slowing down lookups on a near-full table, we resize the table when | 
 | 95 | it is more than half filled. | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 96 | */ | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 97 | typedef struct dictobject dictobject; | 
 | 98 | struct dictobject { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 99 | 	PyObject_HEAD | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 100 | 	int ma_fill;  /* # Active + # Dummy */ | 
 | 101 | 	int ma_used;  /* # Active */ | 
 | 102 | 	int ma_size;  /* total # slots in ma_table */ | 
 | 103 | 	int ma_poly;  /* appopriate entry from polys vector */ | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 104 | 	dictentry *ma_table; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 105 | 	dictentry *(*ma_lookup)(dictobject *mp, PyObject *key, long hash); | 
 | 106 | }; | 
 | 107 |  | 
 | 108 | /* forward declarations */ | 
 | 109 | static dictentry * | 
 | 110 | lookdict_string(dictobject *mp, PyObject *key, long hash); | 
 | 111 |  | 
 | 112 | #ifdef SHOW_CONVERSION_COUNTS | 
 | 113 | static long created = 0L; | 
 | 114 | static long converted = 0L; | 
 | 115 |  | 
 | 116 | static void | 
 | 117 | show_counts(void) | 
 | 118 | { | 
 | 119 | 	fprintf(stderr, "created %ld string dicts\n", created); | 
 | 120 | 	fprintf(stderr, "converted %ld to normal dicts\n", converted); | 
 | 121 | 	fprintf(stderr, "%.2f%% conversion rate\n", (100.0*converted)/created); | 
 | 122 | } | 
 | 123 | #endif | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 124 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 125 | PyObject * | 
| Thomas Wouters | 7889010 | 2000-07-22 19:25:51 +0000 | [diff] [blame] | 126 | PyDict_New(void) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 127 | { | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 128 | 	register dictobject *mp; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 129 | 	if (dummy == NULL) { /* Auto-initialize dummy */ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 130 | 		dummy = PyString_FromString("<dummy key>"); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 131 | 		if (dummy == NULL) | 
 | 132 | 			return NULL; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 133 | #ifdef SHOW_CONVERSION_COUNTS | 
 | 134 | 		Py_AtExit(show_counts); | 
 | 135 | #endif | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 136 | 	} | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 137 | 	mp = PyObject_NEW(dictobject, &PyDict_Type); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 138 | 	if (mp == NULL) | 
 | 139 | 		return NULL; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 140 | 	mp->ma_size = 0; | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 141 | 	mp->ma_poly = 0; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 142 | 	mp->ma_table = NULL; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 143 | 	mp->ma_fill = 0; | 
 | 144 | 	mp->ma_used = 0; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 145 | 	mp->ma_lookup = lookdict_string; | 
 | 146 | #ifdef SHOW_CONVERSION_COUNTS | 
 | 147 | 	++created; | 
 | 148 | #endif | 
| Jeremy Hylton | c5007aa | 2000-06-30 05:02:53 +0000 | [diff] [blame] | 149 | 	PyObject_GC_Init(mp); | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 150 | 	return (PyObject *)mp; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 151 | } | 
 | 152 |  | 
 | 153 | /* | 
 | 154 | The basic lookup function used by all operations. | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 155 | This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4. | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 156 | Open addressing is preferred over chaining since the link overhead for | 
 | 157 | chaining would be substantial (100% with typical malloc overhead). | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 158 | However, instead of going through the table at constant steps, we cycle | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 159 | through the values of GF(2^n).  This avoids modulo computations, being | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 160 | much cheaper on RISC machines, without leading to clustering. | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 161 |  | 
| Guido van Rossum | 2bc1379 | 1999-03-24 19:06:42 +0000 | [diff] [blame] | 162 | The initial probe index is computed as hash mod the table size. | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 163 | Subsequent probe indices use the values of x^i in GF(2^n)-{0} as an offset, | 
 | 164 | where x is a root. The initial offset is derived from hash, too. | 
| Guido van Rossum | 2bc1379 | 1999-03-24 19:06:42 +0000 | [diff] [blame] | 165 |  | 
 | 166 | All arithmetic on hash should ignore overflow. | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 167 |  | 
 | 168 | (This version is due to Reimer Behrends, some ideas are also due to | 
| Guido van Rossum | fd7a0b8 | 1997-08-18 21:52:47 +0000 | [diff] [blame] | 169 | Jyrki Alakuijala and Vladimir Marangozov.) | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 170 |  | 
 | 171 | This function must never return NULL; failures are indicated by returning | 
 | 172 | a dictentry* for which the me_value field is NULL.  Exceptions are never | 
 | 173 | reported by this function, and outstanding exceptions are maintained. | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 174 | */ | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 175 | static dictentry * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 176 | lookdict(dictobject *mp, PyObject *key, register long hash) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 177 | { | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 178 | 	register int i; | 
 | 179 | 	register unsigned incr; | 
| Guido van Rossum | fd7a0b8 | 1997-08-18 21:52:47 +0000 | [diff] [blame] | 180 | 	register dictentry *freeslot; | 
| Guido van Rossum | 2095d24 | 1997-04-09 19:41:24 +0000 | [diff] [blame] | 181 | 	register unsigned int mask = mp->ma_size-1; | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 182 | 	dictentry *ep0 = mp->ma_table; | 
 | 183 | 	register dictentry *ep; | 
| Fred Drake | c88b99c | 2000-08-31 19:04:07 +0000 | [diff] [blame] | 184 | 	register int restore_error = 0; | 
 | 185 | 	register int checked_error = 0; | 
 | 186 | 	register int cmp; | 
 | 187 | 	PyObject *err_type, *err_value, *err_tb; | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 188 | 	/* We must come up with (i, incr) such that 0 <= i < ma_size | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 189 | 	   and 0 < incr < ma_size and both are a function of hash. | 
 | 190 | 	   i is the initial table index and incr the initial probe offset. */ | 
| Guido van Rossum | fd7a0b8 | 1997-08-18 21:52:47 +0000 | [diff] [blame] | 191 | 	i = (~hash) & mask; | 
 | 192 | 	/* We use ~hash instead of hash, as degenerate hash functions, such | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 193 | 	   as for ints <sigh>, can have lots of leading zeros. It's not | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 194 | 	   really a performance risk, but better safe than sorry. | 
 | 195 | 	   12-Dec-00 tim:  so ~hash produces lots of leading ones instead -- | 
 | 196 | 	   what's the gain? */ | 
| Guido van Rossum | efb4609 | 1997-01-29 15:53:56 +0000 | [diff] [blame] | 197 | 	ep = &ep0[i]; | 
| Guido van Rossum | c1c7b1a | 1998-10-06 16:01:14 +0000 | [diff] [blame] | 198 | 	if (ep->me_key == NULL || ep->me_key == key) | 
| Guido van Rossum | 7d18159 | 1997-01-16 21:06:45 +0000 | [diff] [blame] | 199 | 		return ep; | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 200 | 	if (ep->me_key == dummy) | 
| Guido van Rossum | 7d18159 | 1997-01-16 21:06:45 +0000 | [diff] [blame] | 201 | 		freeslot = ep; | 
| Guido van Rossum | fd7a0b8 | 1997-08-18 21:52:47 +0000 | [diff] [blame] | 202 | 	else { | 
| Fred Drake | c88b99c | 2000-08-31 19:04:07 +0000 | [diff] [blame] | 203 | 		if (ep->me_hash == hash) { | 
 | 204 | 			/* error can't have been checked yet */ | 
 | 205 | 			checked_error = 1; | 
 | 206 | 			if (PyErr_Occurred()) { | 
 | 207 | 				restore_error = 1; | 
 | 208 | 				PyErr_Fetch(&err_type, &err_value, &err_tb); | 
 | 209 | 			} | 
 | 210 | 			cmp = PyObject_Compare(ep->me_key, key); | 
 | 211 | 			if (PyErr_Occurred()) | 
 | 212 | 				PyErr_Clear(); | 
 | 213 | 			else if (cmp == 0) { | 
 | 214 | 				if (restore_error) | 
 | 215 | 					PyErr_Restore(err_type, err_value, | 
 | 216 | 						      err_tb); | 
 | 217 | 				return ep; | 
 | 218 | 			} | 
| Guido van Rossum | fd7a0b8 | 1997-08-18 21:52:47 +0000 | [diff] [blame] | 219 | 		} | 
 | 220 | 		freeslot = NULL; | 
| Guido van Rossum | 2a61e74 | 1997-01-18 07:55:05 +0000 | [diff] [blame] | 221 | 	} | 
| Guido van Rossum | 2bc1379 | 1999-03-24 19:06:42 +0000 | [diff] [blame] | 222 | 	/* Derive incr from hash, just to make it more arbitrary. Note that | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 223 | 	   incr must not be 0, or we will get into an infinite loop.*/ | 
| Guido van Rossum | fd7a0b8 | 1997-08-18 21:52:47 +0000 | [diff] [blame] | 224 | 	incr = (hash ^ ((unsigned long)hash >> 3)) & mask; | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 225 | 	if (!incr) | 
 | 226 | 		incr = mask; | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 227 | 	for (;;) { | 
| Guido van Rossum | efb4609 | 1997-01-29 15:53:56 +0000 | [diff] [blame] | 228 | 		ep = &ep0[(i+incr)&mask]; | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 229 | 		if (ep->me_key == NULL) { | 
| Fred Drake | c88b99c | 2000-08-31 19:04:07 +0000 | [diff] [blame] | 230 | 			if (restore_error) | 
 | 231 | 				PyErr_Restore(err_type, err_value, err_tb); | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 232 | 			if (freeslot != NULL) | 
 | 233 | 				return freeslot; | 
 | 234 | 			else | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 235 | 				return ep; | 
 | 236 | 		} | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 237 | 		if (ep->me_key == dummy) { | 
 | 238 | 			if (freeslot == NULL) | 
 | 239 | 				freeslot = ep; | 
 | 240 | 		} | 
| Fred Drake | c88b99c | 2000-08-31 19:04:07 +0000 | [diff] [blame] | 241 | 		else if (ep->me_key == key) { | 
 | 242 | 			if (restore_error) | 
 | 243 | 				PyErr_Restore(err_type, err_value, err_tb); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 244 | 			return ep; | 
| Fred Drake | c88b99c | 2000-08-31 19:04:07 +0000 | [diff] [blame] | 245 |                 } | 
 | 246 |                 else if (ep->me_hash == hash) { | 
 | 247 | 			if (!checked_error) { | 
 | 248 | 				checked_error = 1; | 
 | 249 | 				if (PyErr_Occurred()) { | 
 | 250 | 					restore_error = 1; | 
 | 251 | 					PyErr_Fetch(&err_type, &err_value, | 
 | 252 | 						    &err_tb); | 
 | 253 | 				} | 
 | 254 | 			} | 
 | 255 | 			cmp = PyObject_Compare(ep->me_key, key); | 
 | 256 | 			if (PyErr_Occurred()) | 
 | 257 | 				PyErr_Clear(); | 
 | 258 | 			else if (cmp == 0) { | 
 | 259 | 				if (restore_error) | 
 | 260 | 					PyErr_Restore(err_type, err_value, | 
 | 261 | 						      err_tb); | 
 | 262 | 				return ep; | 
 | 263 | 			} | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 264 | 		} | 
 | 265 | 		/* Cycle through GF(2^n)-{0} */ | 
 | 266 | 		incr = incr << 1; | 
 | 267 | 		if (incr > mask) | 
| Thomas Wouters | 7e47402 | 2000-07-16 12:04:32 +0000 | [diff] [blame] | 268 | 			incr ^= mp->ma_poly; /* This will implicitly clear | 
| Guido van Rossum | f05fc71 | 1998-11-16 22:46:30 +0000 | [diff] [blame] | 269 | 						the highest bit */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 270 | 	} | 
 | 271 | } | 
 | 272 |  | 
 | 273 | /* | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 274 |  * Hacked up version of lookdict which can assume keys are always strings; | 
 | 275 |  * this assumption allows testing for errors during PyObject_Compare() to | 
 | 276 |  * be dropped; string-string comparisons never raise exceptions.  This also | 
 | 277 |  * means we don't need to go through PyObject_Compare(); we can always use | 
 | 278 |  * the tp_compare slot of the string type object directly. | 
 | 279 |  * | 
 | 280 |  * This really only becomes meaningful if proper error handling in lookdict() | 
 | 281 |  * is too expensive. | 
 | 282 |  */ | 
 | 283 | static dictentry * | 
 | 284 | lookdict_string(dictobject *mp, PyObject *key, register long hash) | 
 | 285 | { | 
 | 286 | 	register int i; | 
 | 287 | 	register unsigned incr; | 
 | 288 | 	register dictentry *freeslot; | 
 | 289 | 	register unsigned int mask = mp->ma_size-1; | 
 | 290 | 	dictentry *ep0 = mp->ma_table; | 
 | 291 | 	register dictentry *ep; | 
 | 292 |         cmpfunc compare = PyString_Type.tp_compare; | 
 | 293 |  | 
 | 294 | 	/* make sure this function doesn't have to handle non-string keys */ | 
 | 295 | 	if (!PyString_Check(key)) { | 
 | 296 | #ifdef SHOW_CONVERSION_COUNTS | 
 | 297 | 		++converted; | 
 | 298 | #endif | 
 | 299 | 		mp->ma_lookup = lookdict; | 
 | 300 | 		return lookdict(mp, key, hash); | 
 | 301 | 	} | 
 | 302 | 	/* We must come up with (i, incr) such that 0 <= i < ma_size | 
 | 303 | 	   and 0 < incr < ma_size and both are a function of hash */ | 
 | 304 | 	i = (~hash) & mask; | 
 | 305 | 	/* We use ~hash instead of hash, as degenerate hash functions, such | 
 | 306 | 	   as for ints <sigh>, can have lots of leading zeros. It's not | 
 | 307 | 	   really a performance risk, but better safe than sorry. */ | 
 | 308 | 	ep = &ep0[i]; | 
 | 309 | 	if (ep->me_key == NULL || ep->me_key == key) | 
 | 310 | 		return ep; | 
 | 311 | 	if (ep->me_key == dummy) | 
 | 312 | 		freeslot = ep; | 
 | 313 | 	else { | 
 | 314 | 		if (ep->me_hash == hash | 
 | 315 |                     && compare(ep->me_key, key) == 0) { | 
 | 316 | 			return ep; | 
 | 317 | 		} | 
 | 318 | 		freeslot = NULL; | 
 | 319 | 	} | 
 | 320 | 	/* Derive incr from hash, just to make it more arbitrary. Note that | 
 | 321 | 	   incr must not be 0, or we will get into an infinite loop.*/ | 
 | 322 | 	incr = (hash ^ ((unsigned long)hash >> 3)) & mask; | 
 | 323 | 	if (!incr) | 
 | 324 | 		incr = mask; | 
 | 325 | 	for (;;) { | 
 | 326 | 		ep = &ep0[(i+incr)&mask]; | 
 | 327 | 		if (ep->me_key == NULL) { | 
 | 328 | 			if (freeslot != NULL) | 
 | 329 | 				return freeslot; | 
 | 330 | 			else | 
 | 331 | 				return ep; | 
 | 332 | 		} | 
 | 333 | 		if (ep->me_key == dummy) { | 
 | 334 | 			if (freeslot == NULL) | 
 | 335 | 				freeslot = ep; | 
 | 336 | 		} | 
 | 337 | 		else if (ep->me_key == key | 
 | 338 | 			 || (ep->me_hash == hash | 
 | 339 | 			     && compare(ep->me_key, key) == 0)) { | 
 | 340 | 			return ep; | 
 | 341 |                 } | 
 | 342 | 		/* Cycle through GF(2^n)-{0} */ | 
 | 343 | 		incr = incr << 1; | 
 | 344 | 		if (incr > mask) | 
 | 345 | 			incr ^= mp->ma_poly; /* This will implicitly clear | 
 | 346 | 						the highest bit */ | 
 | 347 | 	} | 
 | 348 | } | 
 | 349 |  | 
 | 350 | /* | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 351 | Internal routine to insert a new item into the table. | 
 | 352 | Used both by the internal resize routine and by the public insert routine. | 
 | 353 | Eats a reference to key and one to value. | 
 | 354 | */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 355 | static void | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 356 | insertdict(register dictobject *mp, PyObject *key, long hash, PyObject *value) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 357 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 358 | 	PyObject *old_value; | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 359 | 	register dictentry *ep; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 360 | 	ep = (mp->ma_lookup)(mp, key, hash); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 361 | 	if (ep->me_value != NULL) { | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 362 | 		old_value = ep->me_value; | 
 | 363 | 		ep->me_value = value; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 364 | 		Py_DECREF(old_value); /* which **CAN** re-enter */ | 
 | 365 | 		Py_DECREF(key); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 366 | 	} | 
 | 367 | 	else { | 
 | 368 | 		if (ep->me_key == NULL) | 
 | 369 | 			mp->ma_fill++; | 
 | 370 | 		else | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 371 | 			Py_DECREF(ep->me_key); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 372 | 		ep->me_key = key; | 
 | 373 | 		ep->me_hash = hash; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 374 | 		ep->me_value = value; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 375 | 		mp->ma_used++; | 
 | 376 | 	} | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 377 | } | 
 | 378 |  | 
 | 379 | /* | 
 | 380 | Restructure the table by allocating a new table and reinserting all | 
 | 381 | items again.  When entries have been deleted, the new table may | 
 | 382 | actually be smaller than the old one. | 
 | 383 | */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 384 | static int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 385 | dictresize(dictobject *mp, int minused) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 386 | { | 
 | 387 | 	register int oldsize = mp->ma_size; | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 388 | 	register int newsize, newpoly; | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 389 | 	register dictentry *oldtable = mp->ma_table; | 
 | 390 | 	register dictentry *newtable; | 
 | 391 | 	register dictentry *ep; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 392 | 	register int i; | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 393 | 	for (i = 0, newsize = MINSIZE; ; i++, newsize <<= 1) { | 
 | 394 | 		if (i > sizeof(polys)/sizeof(polys[0])) { | 
 | 395 | 			/* Ran out of polynomials */ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 396 | 			PyErr_NoMemory(); | 
| Guido van Rossum | 1d5735e | 1994-08-30 08:27:36 +0000 | [diff] [blame] | 397 | 			return -1; | 
 | 398 | 		} | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 399 | 		if (newsize > minused) { | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 400 | 			newpoly = polys[i]; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 401 | 			break; | 
 | 402 | 		} | 
 | 403 | 	} | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 404 | 	newtable = PyMem_NEW(dictentry, newsize); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 405 | 	if (newtable == NULL) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 406 | 		PyErr_NoMemory(); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 407 | 		return -1; | 
 | 408 | 	} | 
| Guido van Rossum | 0fd0033 | 1998-07-16 15:06:13 +0000 | [diff] [blame] | 409 | 	memset(newtable, '\0', sizeof(dictentry) * newsize); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 410 | 	mp->ma_size = newsize; | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 411 | 	mp->ma_poly = newpoly; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 412 | 	mp->ma_table = newtable; | 
 | 413 | 	mp->ma_fill = 0; | 
 | 414 | 	mp->ma_used = 0; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 415 |  | 
 | 416 | 	/* Make two passes, so we can avoid decrefs | 
 | 417 | 	   (and possible side effects) till the table is copied */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 418 | 	for (i = 0, ep = oldtable; i < oldsize; i++, ep++) { | 
 | 419 | 		if (ep->me_value != NULL) | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 420 | 			insertdict(mp,ep->me_key,ep->me_hash,ep->me_value); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 421 | 	} | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 422 | 	for (i = 0, ep = oldtable; i < oldsize; i++, ep++) { | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 423 | 		if (ep->me_value == NULL) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 424 | 			Py_XDECREF(ep->me_key); | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 425 | 		} | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 426 | 	} | 
 | 427 |  | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 428 | 	if (oldtable != NULL) | 
 | 429 | 		PyMem_DEL(oldtable); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 430 | 	return 0; | 
 | 431 | } | 
 | 432 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 433 | PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 434 | PyDict_GetItem(PyObject *op, PyObject *key) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 435 | { | 
 | 436 | 	long hash; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 437 | 	dictobject *mp = (dictobject *)op; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 438 | 	if (!PyDict_Check(op)) { | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 439 | 		return NULL; | 
 | 440 | 	} | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 441 | 	if (mp->ma_table == NULL) | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 442 | 		return NULL; | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 443 | #ifdef CACHE_HASH | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 444 | 	if (!PyString_Check(key) || | 
 | 445 | 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 446 | #endif | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 447 | 	{ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 448 | 		hash = PyObject_Hash(key); | 
| Guido van Rossum | 474b19e | 1998-05-14 01:00:51 +0000 | [diff] [blame] | 449 | 		if (hash == -1) { | 
 | 450 | 			PyErr_Clear(); | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 451 | 			return NULL; | 
| Guido van Rossum | 474b19e | 1998-05-14 01:00:51 +0000 | [diff] [blame] | 452 | 		} | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 453 | 	} | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 454 | 	return (mp->ma_lookup)(mp, key, hash)->me_value; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 455 | } | 
 | 456 |  | 
 | 457 | int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 458 | PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 459 | { | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 460 | 	register dictobject *mp; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 461 | 	register long hash; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 462 | 	if (!PyDict_Check(op)) { | 
 | 463 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 464 | 		return -1; | 
 | 465 | 	} | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 466 | 	mp = (dictobject *)op; | 
| Guido van Rossum | 2a61e74 | 1997-01-18 07:55:05 +0000 | [diff] [blame] | 467 | #ifdef CACHE_HASH | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 468 | 	if (PyString_Check(key)) { | 
| Guido van Rossum | 2a61e74 | 1997-01-18 07:55:05 +0000 | [diff] [blame] | 469 | #ifdef INTERN_STRINGS | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 470 | 		if (((PyStringObject *)key)->ob_sinterned != NULL) { | 
 | 471 | 			key = ((PyStringObject *)key)->ob_sinterned; | 
 | 472 | 			hash = ((PyStringObject *)key)->ob_shash; | 
| Guido van Rossum | 2a61e74 | 1997-01-18 07:55:05 +0000 | [diff] [blame] | 473 | 		} | 
 | 474 | 		else | 
 | 475 | #endif | 
 | 476 | 		{ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 477 | 			hash = ((PyStringObject *)key)->ob_shash; | 
| Guido van Rossum | 2a61e74 | 1997-01-18 07:55:05 +0000 | [diff] [blame] | 478 | 			if (hash == -1) | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 479 | 				hash = PyObject_Hash(key); | 
| Guido van Rossum | 2a61e74 | 1997-01-18 07:55:05 +0000 | [diff] [blame] | 480 | 		} | 
 | 481 | 	} | 
 | 482 | 	else | 
 | 483 | #endif | 
 | 484 | 	{ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 485 | 		hash = PyObject_Hash(key); | 
| Guido van Rossum | 2a61e74 | 1997-01-18 07:55:05 +0000 | [diff] [blame] | 486 | 		if (hash == -1) | 
 | 487 | 			return -1; | 
| Guido van Rossum | 2a61e74 | 1997-01-18 07:55:05 +0000 | [diff] [blame] | 488 | 	} | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 489 | 	/* if fill >= 2/3 size, double in size */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 490 | 	if (mp->ma_fill*3 >= mp->ma_size*2) { | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 491 | 		if (dictresize(mp, mp->ma_used*2) != 0) { | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 492 | 			if (mp->ma_fill+1 > mp->ma_size) | 
 | 493 | 				return -1; | 
 | 494 | 		} | 
 | 495 | 	} | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 496 | 	Py_INCREF(value); | 
 | 497 | 	Py_INCREF(key); | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 498 | 	insertdict(mp, key, hash, value); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 499 | 	return 0; | 
 | 500 | } | 
 | 501 |  | 
 | 502 | int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 503 | PyDict_DelItem(PyObject *op, PyObject *key) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 504 | { | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 505 | 	register dictobject *mp; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 506 | 	register long hash; | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 507 | 	register dictentry *ep; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 508 | 	PyObject *old_value, *old_key; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 509 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 510 | 	if (!PyDict_Check(op)) { | 
 | 511 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 512 | 		return -1; | 
 | 513 | 	} | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 514 | #ifdef CACHE_HASH | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 515 | 	if (!PyString_Check(key) || | 
 | 516 | 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 517 | #endif | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 518 | 	{ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 519 | 		hash = PyObject_Hash(key); | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 520 | 		if (hash == -1) | 
 | 521 | 			return -1; | 
 | 522 | 	} | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 523 | 	mp = (dictobject *)op; | 
 | 524 | 	if (((dictobject *)op)->ma_table == NULL) | 
| Guido van Rossum | efc8713 | 1995-01-02 19:42:39 +0000 | [diff] [blame] | 525 | 		goto empty; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 526 | 	ep = (mp->ma_lookup)(mp, key, hash); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 527 | 	if (ep->me_value == NULL) { | 
| Guido van Rossum | efc8713 | 1995-01-02 19:42:39 +0000 | [diff] [blame] | 528 | 	empty: | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 529 | 		PyErr_SetObject(PyExc_KeyError, key); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 530 | 		return -1; | 
 | 531 | 	} | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 532 | 	old_key = ep->me_key; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 533 | 	Py_INCREF(dummy); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 534 | 	ep->me_key = dummy; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 535 | 	old_value = ep->me_value; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 536 | 	ep->me_value = NULL; | 
 | 537 | 	mp->ma_used--; | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 538 | 	Py_DECREF(old_value); | 
 | 539 | 	Py_DECREF(old_key); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 540 | 	return 0; | 
 | 541 | } | 
 | 542 |  | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 543 | void | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 544 | PyDict_Clear(PyObject *op) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 545 | { | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 546 | 	int i, n; | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 547 | 	register dictentry *table; | 
 | 548 | 	dictobject *mp; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 549 | 	if (!PyDict_Check(op)) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 550 | 		return; | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 551 | 	mp = (dictobject *)op; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 552 | 	table = mp->ma_table; | 
 | 553 | 	if (table == NULL) | 
 | 554 | 		return; | 
 | 555 | 	n = mp->ma_size; | 
 | 556 | 	mp->ma_size = mp->ma_used = mp->ma_fill = 0; | 
 | 557 | 	mp->ma_table = NULL; | 
 | 558 | 	for (i = 0; i < n; i++) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 559 | 		Py_XDECREF(table[i].me_key); | 
 | 560 | 		Py_XDECREF(table[i].me_value); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 561 | 	} | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 562 | 	PyMem_DEL(table); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 563 | } | 
 | 564 |  | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 565 | int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 566 | PyDict_Next(PyObject *op, int *ppos, PyObject **pkey, PyObject **pvalue) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 567 | { | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 568 | 	int i; | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 569 | 	register dictobject *mp; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 570 | 	if (!PyDict_Check(op)) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 571 | 		return 0; | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 572 | 	mp = (dictobject *)op; | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 573 | 	i = *ppos; | 
 | 574 | 	if (i < 0) | 
 | 575 | 		return 0; | 
 | 576 | 	while (i < mp->ma_size && mp->ma_table[i].me_value == NULL) | 
 | 577 | 		i++; | 
 | 578 | 	*ppos = i+1; | 
 | 579 | 	if (i >= mp->ma_size) | 
 | 580 | 		return 0; | 
 | 581 | 	if (pkey) | 
 | 582 | 		*pkey = mp->ma_table[i].me_key; | 
 | 583 | 	if (pvalue) | 
 | 584 | 		*pvalue = mp->ma_table[i].me_value; | 
 | 585 | 	return 1; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 586 | } | 
 | 587 |  | 
 | 588 | /* Methods */ | 
 | 589 |  | 
 | 590 | static void | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 591 | dict_dealloc(register dictobject *mp) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 592 | { | 
 | 593 | 	register int i; | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 594 | 	register dictentry *ep; | 
| Guido van Rossum | d724b23 | 2000-03-13 16:01:29 +0000 | [diff] [blame] | 595 | 	Py_TRASHCAN_SAFE_BEGIN(mp) | 
| Jeremy Hylton | c5007aa | 2000-06-30 05:02:53 +0000 | [diff] [blame] | 596 | 	PyObject_GC_Fini(mp); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 597 | 	for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) { | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 598 | 		if (ep->me_key != NULL) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 599 | 			Py_DECREF(ep->me_key); | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 600 | 		} | 
 | 601 | 		if (ep->me_value != NULL) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 602 | 			Py_DECREF(ep->me_value); | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 603 | 		} | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 604 | 	} | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 605 | 	if (mp->ma_table != NULL) | 
 | 606 | 		PyMem_DEL(mp->ma_table); | 
| Guido van Rossum | 4cc6ac7 | 2000-07-01 01:00:38 +0000 | [diff] [blame] | 607 | 	mp = (dictobject *) PyObject_AS_GC(mp); | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 608 | 	PyObject_DEL(mp); | 
| Guido van Rossum | d724b23 | 2000-03-13 16:01:29 +0000 | [diff] [blame] | 609 | 	Py_TRASHCAN_SAFE_END(mp) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 610 | } | 
 | 611 |  | 
 | 612 | static int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 613 | dict_print(register dictobject *mp, register FILE *fp, register int flags) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 614 | { | 
 | 615 | 	register int i; | 
 | 616 | 	register int any; | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 617 | 	register dictentry *ep; | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 618 |  | 
 | 619 | 	i = Py_ReprEnter((PyObject*)mp); | 
 | 620 | 	if (i != 0) { | 
 | 621 | 		if (i < 0) | 
 | 622 | 			return i; | 
 | 623 | 		fprintf(fp, "{...}"); | 
 | 624 | 		return 0; | 
 | 625 | 	} | 
 | 626 |  | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 627 | 	fprintf(fp, "{"); | 
 | 628 | 	any = 0; | 
 | 629 | 	for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) { | 
 | 630 | 		if (ep->me_value != NULL) { | 
 | 631 | 			if (any++ > 0) | 
 | 632 | 				fprintf(fp, ", "); | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 633 | 			if (PyObject_Print((PyObject *)ep->me_key, fp, 0)!=0) { | 
 | 634 | 				Py_ReprLeave((PyObject*)mp); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 635 | 				return -1; | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 636 | 			} | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 637 | 			fprintf(fp, ": "); | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 638 | 			if (PyObject_Print(ep->me_value, fp, 0) != 0) { | 
 | 639 | 				Py_ReprLeave((PyObject*)mp); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 640 | 				return -1; | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 641 | 			} | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 642 | 		} | 
 | 643 | 	} | 
 | 644 | 	fprintf(fp, "}"); | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 645 | 	Py_ReprLeave((PyObject*)mp); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 646 | 	return 0; | 
 | 647 | } | 
 | 648 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 649 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 650 | dict_repr(dictobject *mp) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 651 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 652 | 	auto PyObject *v; | 
 | 653 | 	PyObject *sepa, *colon; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 654 | 	register int i; | 
 | 655 | 	register int any; | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 656 | 	register dictentry *ep; | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 657 |  | 
 | 658 | 	i = Py_ReprEnter((PyObject*)mp); | 
 | 659 | 	if (i != 0) { | 
 | 660 | 		if (i > 0) | 
 | 661 | 			return PyString_FromString("{...}"); | 
 | 662 | 		return NULL; | 
 | 663 | 	} | 
 | 664 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 665 | 	v = PyString_FromString("{"); | 
 | 666 | 	sepa = PyString_FromString(", "); | 
 | 667 | 	colon = PyString_FromString(": "); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 668 | 	any = 0; | 
| Guido van Rossum | 1d5735e | 1994-08-30 08:27:36 +0000 | [diff] [blame] | 669 | 	for (i = 0, ep = mp->ma_table; i < mp->ma_size && v; i++, ep++) { | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 670 | 		if (ep->me_value != NULL) { | 
 | 671 | 			if (any++) | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 672 | 				PyString_Concat(&v, sepa); | 
 | 673 | 			PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_key)); | 
 | 674 | 			PyString_Concat(&v, colon); | 
 | 675 | 			PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_value)); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 676 | 		} | 
 | 677 | 	} | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 678 | 	PyString_ConcatAndDel(&v, PyString_FromString("}")); | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 679 | 	Py_ReprLeave((PyObject*)mp); | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 680 | 	Py_XDECREF(sepa); | 
 | 681 | 	Py_XDECREF(colon); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 682 | 	return v; | 
 | 683 | } | 
 | 684 |  | 
 | 685 | static int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 686 | dict_length(dictobject *mp) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 687 | { | 
 | 688 | 	return mp->ma_used; | 
 | 689 | } | 
 | 690 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 691 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 692 | dict_subscript(dictobject *mp, register PyObject *key) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 693 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 694 | 	PyObject *v; | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 695 | 	long hash; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 696 | 	if (mp->ma_table == NULL) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 697 | 		PyErr_SetObject(PyExc_KeyError, key); | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 698 | 		return NULL; | 
 | 699 | 	} | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 700 | #ifdef CACHE_HASH | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 701 | 	if (!PyString_Check(key) || | 
 | 702 | 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 703 | #endif | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 704 | 	{ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 705 | 		hash = PyObject_Hash(key); | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 706 | 		if (hash == -1) | 
 | 707 | 			return NULL; | 
 | 708 | 	} | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 709 | 	v = (mp->ma_lookup)(mp, key, hash) -> me_value; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 710 | 	if (v == NULL) | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 711 | 		PyErr_SetObject(PyExc_KeyError, key); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 712 | 	else | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 713 | 		Py_INCREF(v); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 714 | 	return v; | 
 | 715 | } | 
 | 716 |  | 
 | 717 | static int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 718 | dict_ass_sub(dictobject *mp, PyObject *v, PyObject *w) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 719 | { | 
 | 720 | 	if (w == NULL) | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 721 | 		return PyDict_DelItem((PyObject *)mp, v); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 722 | 	else | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 723 | 		return PyDict_SetItem((PyObject *)mp, v, w); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 724 | } | 
 | 725 |  | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 726 | static PyMappingMethods dict_as_mapping = { | 
 | 727 | 	(inquiry)dict_length, /*mp_length*/ | 
 | 728 | 	(binaryfunc)dict_subscript, /*mp_subscript*/ | 
 | 729 | 	(objobjargproc)dict_ass_sub, /*mp_ass_subscript*/ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 730 | }; | 
 | 731 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 732 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 733 | dict_keys(register dictobject *mp, PyObject *args) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 734 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 735 | 	register PyObject *v; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 736 | 	register int i, j; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 737 | 	if (!PyArg_NoArgs(args)) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 738 | 		return NULL; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 739 | 	v = PyList_New(mp->ma_used); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 740 | 	if (v == NULL) | 
 | 741 | 		return NULL; | 
 | 742 | 	for (i = 0, j = 0; i < mp->ma_size; i++) { | 
 | 743 | 		if (mp->ma_table[i].me_value != NULL) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 744 | 			PyObject *key = mp->ma_table[i].me_key; | 
 | 745 | 			Py_INCREF(key); | 
 | 746 | 			PyList_SetItem(v, j, key); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 747 | 			j++; | 
 | 748 | 		} | 
 | 749 | 	} | 
 | 750 | 	return v; | 
 | 751 | } | 
 | 752 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 753 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 754 | dict_values(register dictobject *mp, PyObject *args) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 755 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 756 | 	register PyObject *v; | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 757 | 	register int i, j; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 758 | 	if (!PyArg_NoArgs(args)) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 759 | 		return NULL; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 760 | 	v = PyList_New(mp->ma_used); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 761 | 	if (v == NULL) | 
 | 762 | 		return NULL; | 
 | 763 | 	for (i = 0, j = 0; i < mp->ma_size; i++) { | 
 | 764 | 		if (mp->ma_table[i].me_value != NULL) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 765 | 			PyObject *value = mp->ma_table[i].me_value; | 
 | 766 | 			Py_INCREF(value); | 
 | 767 | 			PyList_SetItem(v, j, value); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 768 | 			j++; | 
 | 769 | 		} | 
 | 770 | 	} | 
 | 771 | 	return v; | 
 | 772 | } | 
 | 773 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 774 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 775 | dict_items(register dictobject *mp, PyObject *args) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 776 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 777 | 	register PyObject *v; | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 778 | 	register int i, j; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 779 | 	if (!PyArg_NoArgs(args)) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 780 | 		return NULL; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 781 | 	v = PyList_New(mp->ma_used); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 782 | 	if (v == NULL) | 
 | 783 | 		return NULL; | 
 | 784 | 	for (i = 0, j = 0; i < mp->ma_size; i++) { | 
 | 785 | 		if (mp->ma_table[i].me_value != NULL) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 786 | 			PyObject *key = mp->ma_table[i].me_key; | 
 | 787 | 			PyObject *value = mp->ma_table[i].me_value; | 
 | 788 | 			PyObject *item = PyTuple_New(2); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 789 | 			if (item == NULL) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 790 | 				Py_DECREF(v); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 791 | 				return NULL; | 
 | 792 | 			} | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 793 | 			Py_INCREF(key); | 
 | 794 | 			PyTuple_SetItem(item, 0, key); | 
 | 795 | 			Py_INCREF(value); | 
 | 796 | 			PyTuple_SetItem(item, 1, value); | 
 | 797 | 			PyList_SetItem(v, j, item); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 798 | 			j++; | 
 | 799 | 		} | 
 | 800 | 	} | 
 | 801 | 	return v; | 
 | 802 | } | 
 | 803 |  | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 804 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 805 | dict_update(register dictobject *mp, PyObject *args) | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 806 | { | 
 | 807 | 	register int i; | 
 | 808 | 	dictobject *other; | 
 | 809 |         dictentry *entry; | 
 | 810 | 	if (!PyArg_Parse(args, "O!", &PyDict_Type, &other)) | 
 | 811 | 		return NULL; | 
| Jeremy Hylton | 1fb6088 | 2001-01-03 22:34:59 +0000 | [diff] [blame] | 812 | 	if (other == mp || other->ma_used == 0) | 
 | 813 | 		goto done; /* a.update(a) or a.update({}); nothing to do */ | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 814 | 	/* Do one big resize at the start, rather than incrementally | 
 | 815 | 	   resizing as we insert new items.  Expect that there will be | 
 | 816 | 	   no (or few) overlapping keys. */ | 
 | 817 | 	if ((mp->ma_fill + other->ma_used)*3 >= mp->ma_size*2) { | 
 | 818 | 		if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0) | 
 | 819 | 			return NULL; | 
 | 820 | 	} | 
 | 821 | 	for (i = 0; i < other->ma_size; i++) { | 
 | 822 | 		entry = &other->ma_table[i]; | 
 | 823 | 		if (entry->me_value != NULL) { | 
 | 824 | 			Py_INCREF(entry->me_key); | 
 | 825 | 			Py_INCREF(entry->me_value); | 
 | 826 | 			insertdict(mp, entry->me_key, entry->me_hash, | 
 | 827 | 				   entry->me_value); | 
 | 828 | 		} | 
 | 829 | 	} | 
 | 830 |   done: | 
 | 831 | 	Py_INCREF(Py_None); | 
 | 832 | 	return Py_None; | 
 | 833 | } | 
 | 834 |  | 
 | 835 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 836 | dict_copy(register dictobject *mp, PyObject *args) | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 837 | { | 
| Jeremy Hylton | a12c7a7 | 2000-03-30 22:27:31 +0000 | [diff] [blame] | 838 | 	if (!PyArg_Parse(args, "")) | 
 | 839 | 		return NULL; | 
 | 840 | 	return PyDict_Copy((PyObject*)mp); | 
 | 841 | } | 
 | 842 |  | 
 | 843 | PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 844 | PyDict_Copy(PyObject *o) | 
| Jeremy Hylton | a12c7a7 | 2000-03-30 22:27:31 +0000 | [diff] [blame] | 845 | { | 
 | 846 | 	register dictobject *mp; | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 847 | 	register int i; | 
 | 848 | 	dictobject *copy; | 
 | 849 |         dictentry *entry; | 
| Jeremy Hylton | a12c7a7 | 2000-03-30 22:27:31 +0000 | [diff] [blame] | 850 |  | 
 | 851 | 	if (o == NULL || !PyDict_Check(o)) { | 
 | 852 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 853 | 		return NULL; | 
| Jeremy Hylton | a12c7a7 | 2000-03-30 22:27:31 +0000 | [diff] [blame] | 854 | 	} | 
 | 855 | 	mp = (dictobject *)o; | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 856 | 	copy = (dictobject *)PyDict_New(); | 
 | 857 | 	if (copy == NULL) | 
 | 858 | 		return NULL; | 
 | 859 | 	if (mp->ma_used > 0) { | 
 | 860 | 		if (dictresize(copy, mp->ma_used*3/2) != 0) | 
 | 861 | 			return NULL; | 
 | 862 | 		for (i = 0; i < mp->ma_size; i++) { | 
 | 863 | 			entry = &mp->ma_table[i]; | 
 | 864 | 			if (entry->me_value != NULL) { | 
 | 865 | 				Py_INCREF(entry->me_key); | 
 | 866 | 				Py_INCREF(entry->me_value); | 
 | 867 | 				insertdict(copy, entry->me_key, entry->me_hash, | 
 | 868 | 					   entry->me_value); | 
 | 869 | 			} | 
 | 870 | 		} | 
 | 871 | 	} | 
 | 872 | 	return (PyObject *)copy; | 
 | 873 | } | 
 | 874 |  | 
| Guido van Rossum | 4199fac | 1993-11-05 10:18:44 +0000 | [diff] [blame] | 875 | int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 876 | PyDict_Size(PyObject *mp) | 
| Guido van Rossum | 4199fac | 1993-11-05 10:18:44 +0000 | [diff] [blame] | 877 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 878 | 	if (mp == NULL || !PyDict_Check(mp)) { | 
 | 879 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | b376a4a | 1993-11-23 17:53:17 +0000 | [diff] [blame] | 880 | 		return 0; | 
| Guido van Rossum | 4199fac | 1993-11-05 10:18:44 +0000 | [diff] [blame] | 881 | 	} | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 882 | 	return ((dictobject *)mp)->ma_used; | 
| Guido van Rossum | 4199fac | 1993-11-05 10:18:44 +0000 | [diff] [blame] | 883 | } | 
 | 884 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 885 | PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 886 | PyDict_Keys(PyObject *mp) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 887 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 888 | 	if (mp == NULL || !PyDict_Check(mp)) { | 
 | 889 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 890 | 		return NULL; | 
 | 891 | 	} | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 892 | 	return dict_keys((dictobject *)mp, (PyObject *)NULL); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 893 | } | 
 | 894 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 895 | PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 896 | PyDict_Values(PyObject *mp) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 897 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 898 | 	if (mp == NULL || !PyDict_Check(mp)) { | 
 | 899 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 900 | 		return NULL; | 
 | 901 | 	} | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 902 | 	return dict_values((dictobject *)mp, (PyObject *)NULL); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 903 | } | 
 | 904 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 905 | PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 906 | PyDict_Items(PyObject *mp) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 907 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 908 | 	if (mp == NULL || !PyDict_Check(mp)) { | 
 | 909 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 910 | 		return NULL; | 
 | 911 | 	} | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 912 | 	return dict_items((dictobject *)mp, (PyObject *)NULL); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 913 | } | 
 | 914 |  | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 915 | #define NEWCMP | 
 | 916 |  | 
 | 917 | #ifdef NEWCMP | 
 | 918 |  | 
 | 919 | /* Subroutine which returns the smallest key in a for which b's value | 
 | 920 |    is different or absent.  The value is returned too, through the | 
 | 921 |    pval argument.  No reference counts are incremented. */ | 
 | 922 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 923 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 924 | characterize(dictobject *a, dictobject *b, PyObject **pval) | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 925 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 926 | 	PyObject *diff = NULL; | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 927 | 	int i; | 
 | 928 |  | 
 | 929 | 	*pval = NULL; | 
 | 930 | 	for (i = 0; i < a->ma_size; i++) { | 
 | 931 | 		if (a->ma_table[i].me_value != NULL) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 932 | 			PyObject *key = a->ma_table[i].me_key; | 
 | 933 | 			PyObject *aval, *bval; | 
| Guido van Rossum | 5b2121b | 1997-05-23 00:01:41 +0000 | [diff] [blame] | 934 | 			/* XXX What if PyObject_Compare raises an exception? */ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 935 | 			if (diff != NULL && PyObject_Compare(key, diff) > 0) | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 936 | 				continue; | 
 | 937 | 			aval = a->ma_table[i].me_value; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 938 | 			bval = PyDict_GetItem((PyObject *)b, key); | 
| Guido van Rossum | 5b2121b | 1997-05-23 00:01:41 +0000 | [diff] [blame] | 939 | 			/* XXX What if PyObject_Compare raises an exception? */ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 940 | 			if (bval == NULL || PyObject_Compare(aval, bval) != 0) | 
 | 941 | 			{ | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 942 | 				diff = key; | 
 | 943 | 				*pval = aval; | 
 | 944 | 			} | 
 | 945 | 		} | 
 | 946 | 	} | 
 | 947 | 	return diff; | 
 | 948 | } | 
 | 949 |  | 
 | 950 | static int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 951 | dict_compare(dictobject *a, dictobject *b) | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 952 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 953 | 	PyObject *adiff, *bdiff, *aval, *bval; | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 954 | 	int res; | 
 | 955 |  | 
 | 956 | 	/* Compare lengths first */ | 
 | 957 | 	if (a->ma_used < b->ma_used) | 
 | 958 | 		return -1;	/* a is shorter */ | 
 | 959 | 	else if (a->ma_used > b->ma_used) | 
 | 960 | 		return 1;	/* b is shorter */ | 
 | 961 | 	/* Same length -- check all keys */ | 
 | 962 | 	adiff = characterize(a, b, &aval); | 
| Guido van Rossum | 5b2121b | 1997-05-23 00:01:41 +0000 | [diff] [blame] | 963 | 	if (PyErr_Occurred()) | 
 | 964 | 		return -1; | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 965 | 	if (adiff == NULL) | 
 | 966 | 		return 0;	/* a is a subset with the same length */ | 
 | 967 | 	bdiff = characterize(b, a, &bval); | 
| Guido van Rossum | 5b2121b | 1997-05-23 00:01:41 +0000 | [diff] [blame] | 968 | 	if (PyErr_Occurred()) | 
 | 969 | 		return -1; | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 970 | 	/* bdiff == NULL would be impossible now */ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 971 | 	res = PyObject_Compare(adiff, bdiff); | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 972 | 	if (res == 0) | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 973 | 		res = PyObject_Compare(aval, bval); | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 974 | 	return res; | 
 | 975 | } | 
 | 976 |  | 
 | 977 | #else /* !NEWCMP */ | 
 | 978 |  | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 979 | static int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 980 | dict_compare(dictobject *a, dictobject *b) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 981 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 982 | 	PyObject *akeys, *bkeys; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 983 | 	int i, n, res; | 
 | 984 | 	if (a == b) | 
 | 985 | 		return 0; | 
 | 986 | 	if (a->ma_used == 0) { | 
 | 987 | 		if (b->ma_used != 0) | 
 | 988 | 			return -1; | 
 | 989 | 		else | 
 | 990 | 			return 0; | 
 | 991 | 	} | 
 | 992 | 	else { | 
 | 993 | 		if (b->ma_used == 0) | 
 | 994 | 			return 1; | 
 | 995 | 	} | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 996 | 	akeys = dict_keys(a, (PyObject *)NULL); | 
 | 997 | 	bkeys = dict_keys(b, (PyObject *)NULL); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 998 | 	if (akeys == NULL || bkeys == NULL) { | 
 | 999 | 		/* Oops, out of memory -- what to do? */ | 
 | 1000 | 		/* For now, sort on address! */ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1001 | 		Py_XDECREF(akeys); | 
 | 1002 | 		Py_XDECREF(bkeys); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1003 | 		if (a < b) | 
 | 1004 | 			return -1; | 
 | 1005 | 		else | 
 | 1006 | 			return 1; | 
 | 1007 | 	} | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1008 | 	PyList_Sort(akeys); | 
 | 1009 | 	PyList_Sort(bkeys); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1010 | 	n = a->ma_used < b->ma_used ? a->ma_used : b->ma_used; /* smallest */ | 
 | 1011 | 	res = 0; | 
 | 1012 | 	for (i = 0; i < n; i++) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1013 | 		PyObject *akey, *bkey, *aval, *bval; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1014 | 		long ahash, bhash; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1015 | 		akey = PyList_GetItem(akeys, i); | 
 | 1016 | 		bkey = PyList_GetItem(bkeys, i); | 
 | 1017 | 		res = PyObject_Compare(akey, bkey); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1018 | 		if (res != 0) | 
 | 1019 | 			break; | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 1020 | #ifdef CACHE_HASH | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1021 | 		if (!PyString_Check(akey) || | 
 | 1022 | 		    (ahash = ((PyStringObject *) akey)->ob_shash) == -1) | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 1023 | #endif | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 1024 | 		{ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1025 | 			ahash = PyObject_Hash(akey); | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 1026 | 			if (ahash == -1) | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1027 | 				PyErr_Clear(); /* Don't want errors here */ | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 1028 | 		} | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 1029 | #ifdef CACHE_HASH | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1030 | 		if (!PyString_Check(bkey) || | 
 | 1031 | 		    (bhash = ((PyStringObject *) bkey)->ob_shash) == -1) | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 1032 | #endif | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 1033 | 		{ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1034 | 			bhash = PyObject_Hash(bkey); | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 1035 | 			if (bhash == -1) | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1036 | 				PyErr_Clear(); /* Don't want errors here */ | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 1037 | 		} | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 1038 | 		aval = (a->ma_lookup)(a, akey, ahash) -> me_value; | 
 | 1039 | 		bval = (b->ma_lookup)(b, bkey, bhash) -> me_value; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1040 | 		res = PyObject_Compare(aval, bval); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1041 | 		if (res != 0) | 
 | 1042 | 			break; | 
 | 1043 | 	} | 
 | 1044 | 	if (res == 0) { | 
 | 1045 | 		if (a->ma_used < b->ma_used) | 
 | 1046 | 			res = -1; | 
 | 1047 | 		else if (a->ma_used > b->ma_used) | 
 | 1048 | 			res = 1; | 
 | 1049 | 	} | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1050 | 	Py_DECREF(akeys); | 
 | 1051 | 	Py_DECREF(bkeys); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1052 | 	return res; | 
 | 1053 | } | 
 | 1054 |  | 
| Guido van Rossum | a0a69b8 | 1996-12-05 21:55:55 +0000 | [diff] [blame] | 1055 | #endif /* !NEWCMP */ | 
 | 1056 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1057 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1058 | dict_has_key(register dictobject *mp, PyObject *args) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1059 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1060 | 	PyObject *key; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1061 | 	long hash; | 
 | 1062 | 	register long ok; | 
| Fred Drake | 52fccfd | 2000-02-23 15:47:16 +0000 | [diff] [blame] | 1063 | 	if (!PyArg_ParseTuple(args, "O:has_key", &key)) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1064 | 		return NULL; | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 1065 | #ifdef CACHE_HASH | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1066 | 	if (!PyString_Check(key) || | 
 | 1067 | 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 1068 | #endif | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 1069 | 	{ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1070 | 		hash = PyObject_Hash(key); | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 1071 | 		if (hash == -1) | 
 | 1072 | 			return NULL; | 
 | 1073 | 	} | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 1074 | 	ok = (mp->ma_size != 0 | 
 | 1075 | 	      && (mp->ma_lookup)(mp, key, hash)->me_value != NULL); | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1076 | 	return PyInt_FromLong(ok); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1077 | } | 
 | 1078 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1079 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1080 | dict_get(register dictobject *mp, PyObject *args) | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1081 | { | 
 | 1082 | 	PyObject *key; | 
| Barry Warsaw | 320ac33 | 1997-10-20 17:26:25 +0000 | [diff] [blame] | 1083 | 	PyObject *failobj = Py_None; | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1084 | 	PyObject *val = NULL; | 
 | 1085 | 	long hash; | 
 | 1086 |  | 
| Fred Drake | 52fccfd | 2000-02-23 15:47:16 +0000 | [diff] [blame] | 1087 | 	if (!PyArg_ParseTuple(args, "O|O:get", &key, &failobj)) | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1088 | 		return NULL; | 
| Guido van Rossum | 6fcfa72 | 1997-10-20 20:10:00 +0000 | [diff] [blame] | 1089 | 	if (mp->ma_table == NULL) | 
 | 1090 | 		goto finally; | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1091 |  | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1092 | #ifdef CACHE_HASH | 
 | 1093 | 	if (!PyString_Check(key) || | 
 | 1094 | 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) | 
 | 1095 | #endif | 
 | 1096 | 	{ | 
 | 1097 | 		hash = PyObject_Hash(key); | 
 | 1098 | 		if (hash == -1) | 
 | 1099 | 			return NULL; | 
 | 1100 | 	} | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 1101 | 	val = (mp->ma_lookup)(mp, key, hash)->me_value; | 
| Barry Warsaw | 320ac33 | 1997-10-20 17:26:25 +0000 | [diff] [blame] | 1102 |  | 
| Guido van Rossum | 6fcfa72 | 1997-10-20 20:10:00 +0000 | [diff] [blame] | 1103 |   finally: | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1104 | 	if (val == NULL) | 
 | 1105 | 		val = failobj; | 
 | 1106 | 	Py_INCREF(val); | 
 | 1107 | 	return val; | 
 | 1108 | } | 
 | 1109 |  | 
 | 1110 |  | 
 | 1111 | static PyObject * | 
| Guido van Rossum | 164452c | 2000-08-08 16:12:54 +0000 | [diff] [blame] | 1112 | dict_setdefault(register dictobject *mp, PyObject *args) | 
 | 1113 | { | 
 | 1114 | 	PyObject *key; | 
 | 1115 | 	PyObject *failobj = Py_None; | 
 | 1116 | 	PyObject *val = NULL; | 
 | 1117 | 	long hash; | 
 | 1118 |  | 
 | 1119 | 	if (!PyArg_ParseTuple(args, "O|O:setdefault", &key, &failobj)) | 
 | 1120 | 		return NULL; | 
 | 1121 | 	if (mp->ma_table == NULL) | 
 | 1122 | 		goto finally; | 
 | 1123 |  | 
 | 1124 | #ifdef CACHE_HASH | 
 | 1125 | 	if (!PyString_Check(key) || | 
 | 1126 | 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) | 
 | 1127 | #endif | 
 | 1128 | 	{ | 
 | 1129 | 		hash = PyObject_Hash(key); | 
 | 1130 | 		if (hash == -1) | 
 | 1131 | 			return NULL; | 
 | 1132 | 	} | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 1133 | 	val = (mp->ma_lookup)(mp, key, hash)->me_value; | 
| Guido van Rossum | 164452c | 2000-08-08 16:12:54 +0000 | [diff] [blame] | 1134 |  | 
 | 1135 |   finally: | 
 | 1136 | 	if (val == NULL) { | 
 | 1137 | 		val = failobj; | 
 | 1138 | 		if (PyDict_SetItem((PyObject*)mp, key, failobj)) | 
 | 1139 | 			val = NULL; | 
 | 1140 | 	} | 
 | 1141 | 	Py_XINCREF(val); | 
 | 1142 | 	return val; | 
 | 1143 | } | 
 | 1144 |  | 
 | 1145 |  | 
 | 1146 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1147 | dict_clear(register dictobject *mp, PyObject *args) | 
| Guido van Rossum | fb8f1ca | 1997-03-21 21:55:12 +0000 | [diff] [blame] | 1148 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1149 | 	if (!PyArg_NoArgs(args)) | 
| Guido van Rossum | fb8f1ca | 1997-03-21 21:55:12 +0000 | [diff] [blame] | 1150 | 		return NULL; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1151 | 	PyDict_Clear((PyObject *)mp); | 
 | 1152 | 	Py_INCREF(Py_None); | 
 | 1153 | 	return Py_None; | 
| Guido van Rossum | fb8f1ca | 1997-03-21 21:55:12 +0000 | [diff] [blame] | 1154 | } | 
 | 1155 |  | 
| Guido van Rossum | ba6ab84 | 2000-12-12 22:02:18 +0000 | [diff] [blame] | 1156 | static PyObject * | 
 | 1157 | dict_popitem(dictobject *mp, PyObject *args) | 
 | 1158 | { | 
 | 1159 | 	int i = 0; | 
 | 1160 | 	dictentry *ep; | 
 | 1161 | 	PyObject *res; | 
 | 1162 |  | 
 | 1163 | 	if (!PyArg_NoArgs(args)) | 
 | 1164 | 		return NULL; | 
 | 1165 | 	if (mp->ma_used == 0) { | 
 | 1166 | 		PyErr_SetString(PyExc_KeyError, | 
 | 1167 | 				"popitem(): dictionary is empty"); | 
 | 1168 | 		return NULL; | 
 | 1169 | 	} | 
 | 1170 | 	/* Set ep to "the first" dict entry with a value.  We abuse the hash | 
 | 1171 | 	 * field of slot 0 to hold a search finger: | 
 | 1172 | 	 * If slot 0 has a value, use slot 0. | 
 | 1173 | 	 * Else slot 0 is being used to hold a search finger, | 
 | 1174 | 	 * and we use its hash value as the first index to look. | 
 | 1175 | 	 */ | 
 | 1176 | 	ep = &mp->ma_table[0]; | 
 | 1177 | 	if (ep->me_value == NULL) { | 
 | 1178 | 		i = (int)ep->me_hash; | 
 | 1179 | 		/* The hash field may be uninitialized trash, or it | 
 | 1180 | 		 * may be a real hash value, or it may be a legit | 
 | 1181 | 		 * search finger, or it may be a once-legit search | 
 | 1182 | 		 * finger that's out of bounds now because it | 
 | 1183 | 		 * wrapped around or the table shrunk -- simply | 
 | 1184 | 		 * make sure it's in bounds now. | 
 | 1185 | 		 */ | 
 | 1186 | 		if (i >= mp->ma_size || i < 1) | 
 | 1187 | 			i = 1;	/* skip slot 0 */ | 
 | 1188 | 		while ((ep = &mp->ma_table[i])->me_value == NULL) { | 
 | 1189 | 			i++; | 
 | 1190 | 			if (i >= mp->ma_size) | 
 | 1191 | 				i = 1; | 
 | 1192 | 		} | 
 | 1193 | 	} | 
 | 1194 | 	res = PyTuple_New(2); | 
 | 1195 | 	if (res != NULL) { | 
 | 1196 | 		PyTuple_SET_ITEM(res, 0, ep->me_key); | 
 | 1197 | 		PyTuple_SET_ITEM(res, 1, ep->me_value); | 
 | 1198 | 		Py_INCREF(dummy); | 
 | 1199 | 		ep->me_key = dummy; | 
 | 1200 | 		ep->me_value = NULL; | 
 | 1201 | 		mp->ma_used--; | 
 | 1202 | 		assert(mp->ma_table[0].me_value == NULL); | 
 | 1203 | 		mp->ma_table[0].me_hash = i + 1;  /* next place to start */ | 
 | 1204 | 	} | 
 | 1205 | 	return res; | 
 | 1206 | } | 
 | 1207 |  | 
| Jeremy Hylton | 8caad49 | 2000-06-23 14:18:11 +0000 | [diff] [blame] | 1208 | static int | 
 | 1209 | dict_traverse(PyObject *op, visitproc visit, void *arg) | 
 | 1210 | { | 
 | 1211 | 	int i = 0, err; | 
 | 1212 | 	PyObject *pk; | 
 | 1213 | 	PyObject *pv; | 
 | 1214 |  | 
 | 1215 | 	while (PyDict_Next(op, &i, &pk, &pv)) { | 
 | 1216 | 		err = visit(pk, arg); | 
 | 1217 | 		if (err) | 
 | 1218 | 			return err; | 
 | 1219 | 		err = visit(pv, arg); | 
 | 1220 | 		if (err) | 
 | 1221 | 			return err; | 
 | 1222 | 	} | 
 | 1223 | 	return 0; | 
 | 1224 | } | 
 | 1225 |  | 
 | 1226 | static int | 
 | 1227 | dict_tp_clear(PyObject *op) | 
 | 1228 | { | 
 | 1229 | 	PyDict_Clear(op); | 
 | 1230 | 	return 0; | 
 | 1231 | } | 
 | 1232 |  | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 1233 |  | 
 | 1234 | static char has_key__doc__[] = | 
 | 1235 | "D.has_key(k) -> 1 if D has a key k, else 0"; | 
 | 1236 |  | 
 | 1237 | static char get__doc__[] = | 
 | 1238 | "D.get(k[,d]) -> D[k] if D.has_key(k), else d.  d defaults to None."; | 
 | 1239 |  | 
 | 1240 | static char setdefault_doc__[] = | 
 | 1241 | "D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if not D.has_key(k)"; | 
 | 1242 |  | 
 | 1243 | static char popitem__doc__[] = | 
 | 1244 | "D.popitem() -> (k, v), remove and return some (key, value) pair as a\n\ | 
 | 1245 | 2-tuple; but raise KeyError if D is empty"; | 
 | 1246 |  | 
 | 1247 | static char keys__doc__[] = | 
 | 1248 | "D.keys() -> list of D's keys"; | 
 | 1249 |  | 
 | 1250 | static char items__doc__[] = | 
 | 1251 | "D.items() -> list of D's (key, value) pairs, as 2-tuples"; | 
 | 1252 |  | 
 | 1253 | static char values__doc__[] = | 
 | 1254 | "D.values() -> list of D's values"; | 
 | 1255 |  | 
 | 1256 | static char update__doc__[] = | 
 | 1257 | "D.update(E) -> None.  Update D from E: for k in E.keys(): D[k] = E[k]"; | 
 | 1258 |  | 
 | 1259 | static char clear__doc__[] = | 
 | 1260 | "D.clear() -> None.  Remove all items from D."; | 
 | 1261 |  | 
 | 1262 | static char copy__doc__[] = | 
 | 1263 | "D.copy() -> a shallow copy of D"; | 
 | 1264 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1265 | static PyMethodDef mapp_methods[] = { | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 1266 | 	{"has_key",	(PyCFunction)dict_has_key,      METH_VARARGS, | 
 | 1267 | 	 has_key__doc__}, | 
 | 1268 | 	{"get",         (PyCFunction)dict_get,          METH_VARARGS, | 
 | 1269 | 	 get__doc__}, | 
 | 1270 | 	{"setdefault",  (PyCFunction)dict_setdefault,   METH_VARARGS, | 
 | 1271 | 	 setdefault_doc__}, | 
 | 1272 | 	{"popitem",	(PyCFunction)dict_popitem,	METH_OLDARGS, | 
 | 1273 | 	 popitem__doc__}, | 
 | 1274 | 	{"keys",	(PyCFunction)dict_keys,		METH_OLDARGS, | 
 | 1275 | 	keys__doc__}, | 
 | 1276 | 	{"items",	(PyCFunction)dict_items,	METH_OLDARGS, | 
 | 1277 | 	 items__doc__}, | 
 | 1278 | 	{"values",	(PyCFunction)dict_values,	METH_OLDARGS, | 
 | 1279 | 	 values__doc__}, | 
 | 1280 | 	{"update",	(PyCFunction)dict_update,	METH_OLDARGS, | 
 | 1281 | 	 update__doc__}, | 
 | 1282 | 	{"clear",	(PyCFunction)dict_clear,	METH_OLDARGS, | 
 | 1283 | 	 clear__doc__}, | 
 | 1284 | 	{"copy",	(PyCFunction)dict_copy,		METH_OLDARGS, | 
 | 1285 | 	 copy__doc__}, | 
 | 1286 | 	{NULL,		NULL}	/* sentinel */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1287 | }; | 
 | 1288 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1289 | static PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1290 | dict_getattr(dictobject *mp, char *name) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1291 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1292 | 	return Py_FindMethod(mapp_methods, (PyObject *)mp, name); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1293 | } | 
 | 1294 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1295 | PyTypeObject PyDict_Type = { | 
 | 1296 | 	PyObject_HEAD_INIT(&PyType_Type) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1297 | 	0, | 
| Guido van Rossum | 9bfef44 | 1993-03-29 10:43:31 +0000 | [diff] [blame] | 1298 | 	"dictionary", | 
| Jeremy Hylton | c5007aa | 2000-06-30 05:02:53 +0000 | [diff] [blame] | 1299 | 	sizeof(dictobject) + PyGC_HEAD_SIZE, | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1300 | 	0, | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 1301 | 	(destructor)dict_dealloc, /*tp_dealloc*/ | 
 | 1302 | 	(printfunc)dict_print, /*tp_print*/ | 
 | 1303 | 	(getattrfunc)dict_getattr, /*tp_getattr*/ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1304 | 	0,			/*tp_setattr*/ | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 1305 | 	(cmpfunc)dict_compare, /*tp_compare*/ | 
 | 1306 | 	(reprfunc)dict_repr, /*tp_repr*/ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1307 | 	0,			/*tp_as_number*/ | 
 | 1308 | 	0,			/*tp_as_sequence*/ | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 1309 | 	&dict_as_mapping,	/*tp_as_mapping*/ | 
| Jeremy Hylton | 8caad49 | 2000-06-23 14:18:11 +0000 | [diff] [blame] | 1310 | 	0,		/* tp_hash */ | 
 | 1311 | 	0,		/* tp_call */ | 
 | 1312 | 	0,		/* tp_str */ | 
 | 1313 | 	0,		/* tp_getattro */ | 
 | 1314 | 	0,		/* tp_setattro */ | 
 | 1315 | 	0,		/* tp_as_buffer */ | 
| Jeremy Hylton | d08b4c4 | 2000-06-23 19:37:02 +0000 | [diff] [blame] | 1316 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/ | 
| Jeremy Hylton | 8caad49 | 2000-06-23 14:18:11 +0000 | [diff] [blame] | 1317 | 	0,		/* tp_doc */ | 
 | 1318 | 	(traverseproc)dict_traverse,	/* tp_traverse */ | 
 | 1319 | 	(inquiry)dict_tp_clear,		/* tp_clear */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1320 | }; | 
 | 1321 |  | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 1322 | /* For backward compatibility with old dictionary interface */ | 
 | 1323 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1324 | PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1325 | PyDict_GetItemString(PyObject *v, char *key) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1326 | { | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 1327 | 	PyObject *kv, *rv; | 
 | 1328 | 	kv = PyString_FromString(key); | 
 | 1329 | 	if (kv == NULL) | 
 | 1330 | 		return NULL; | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 1331 | 	rv = PyDict_GetItem(v, kv); | 
 | 1332 | 	Py_DECREF(kv); | 
 | 1333 | 	return rv; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1334 | } | 
 | 1335 |  | 
 | 1336 | int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1337 | PyDict_SetItemString(PyObject *v, char *key, PyObject *item) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1338 | { | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 1339 | 	PyObject *kv; | 
 | 1340 | 	int err; | 
 | 1341 | 	kv = PyString_FromString(key); | 
 | 1342 | 	if (kv == NULL) | 
| Guido van Rossum | 037b220 | 1997-05-20 18:35:19 +0000 | [diff] [blame] | 1343 | 		return -1; | 
| Guido van Rossum | 4f3bf1e | 1997-09-29 23:31:11 +0000 | [diff] [blame] | 1344 | 	PyString_InternInPlace(&kv); /* XXX Should we really? */ | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 1345 | 	err = PyDict_SetItem(v, kv, item); | 
 | 1346 | 	Py_DECREF(kv); | 
 | 1347 | 	return err; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1348 | } | 
 | 1349 |  | 
 | 1350 | int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1351 | PyDict_DelItemString(PyObject *v, char *key) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1352 | { | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 1353 | 	PyObject *kv; | 
 | 1354 | 	int err; | 
 | 1355 | 	kv = PyString_FromString(key); | 
 | 1356 | 	if (kv == NULL) | 
| Guido van Rossum | 037b220 | 1997-05-20 18:35:19 +0000 | [diff] [blame] | 1357 | 		return -1; | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 1358 | 	err = PyDict_DelItem(v, kv); | 
 | 1359 | 	Py_DECREF(kv); | 
 | 1360 | 	return err; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1361 | } |