Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(13)

Side by Side Diff: Modules/cPickle.c

Issue 91044: Fix the last regression shown by cvs2svn (Closed) SVN Base: http://unladen-swallow.googlecode.com/svn/trunk/
Patch Set: Created 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 #include "Python.h" 1 #include "Python.h"
2 #include "structmember.h" 2 #include "structmember.h"
3 #include "cPickle.h" 3 #include "cPickle.h"
4 4
5 PyDoc_STRVAR(cPickle_module_documentation, 5 PyDoc_STRVAR(cPickle_module_documentation,
6 "C implementation and optimization of the Python pickle module."); 6 "C implementation and optimization of the Python pickle module.");
7 7
8 #ifndef Py_eval_input 8 #ifndef Py_eval_input
9 #include <graminit.h> 9 #include <graminit.h>
10 #define Py_eval_input eval_input 10 #define Py_eval_input eval_input
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 return NULL; 344 return NULL;
345 } 345 }
346 memset(memo->mt_table, 0, MT_MINSIZE * sizeof(PyMemoEntry)); 346 memset(memo->mt_table, 0, MT_MINSIZE * sizeof(PyMemoEntry));
347 347
348 return memo; 348 return memo;
349 } 349 }
350 350
351 STATIC_MEMOTABLE PyMemoTable * 351 STATIC_MEMOTABLE PyMemoTable *
352 PyMemoTable_Copy(PyMemoTable *self) 352 PyMemoTable_Copy(PyMemoTable *self)
353 { 353 {
354 Py_ssize_t i;
354 PyMemoTable *new = PyMemoTable_New(); 355 PyMemoTable *new = PyMemoTable_New();
355 if (new == NULL) 356 if (new == NULL)
356 return NULL; 357 return NULL;
357 358
358 new->mt_used = self->mt_used; 359 new->mt_used = self->mt_used;
359 new->mt_allocated = self->mt_allocated; 360 new->mt_allocated = self->mt_allocated;
360 new->mt_mask = self->mt_mask; 361 new->mt_mask = self->mt_mask;
361 /* The table we get from _New() is probably smaller than we wanted. 362 /* The table we get from _New() is probably smaller than we wanted.
362 Free it and allocate one that's the right size. */ 363 Free it and allocate one that's the right size. */
363 PyMem_FREE(new->mt_table); 364 PyMem_FREE(new->mt_table);
364 new->mt_table = PyMem_NEW(PyMemoEntry, self->mt_allocated); 365 new->mt_table = PyMem_NEW(PyMemoEntry, self->mt_allocated);
365 if (new->mt_table == NULL) { 366 if (new->mt_table == NULL) {
366 PyMem_FREE(new); 367 PyMem_FREE(new);
367 return NULL; 368 return NULL;
369 }
370 for (i = 0; i < self->mt_allocated; i++) {
371 Py_XINCREF(self->mt_table[i].me_key);
368 } 372 }
369 memcpy(new->mt_table, self->mt_table, 373 memcpy(new->mt_table, self->mt_table,
370 sizeof(PyMemoEntry) * self->mt_allocated); 374 sizeof(PyMemoEntry) * self->mt_allocated);
371 375
372 return new; 376 return new;
373 } 377 }
374 378
375 STATIC_MEMOTABLE void 379 STATIC_MEMOTABLE void
376 PyMemoTable_Del(PyMemoTable *self) 380 PyMemoTable_Del(PyMemoTable *self)
377 { 381 {
382 Py_ssize_t i;
Jeffrey Yasskin 2009/07/03 01:32:59 Just call PyMemoTable_Clear()? The extra memset sh
383 for (i = 0; i < self->mt_allocated; i++) {
384 Py_XDECREF(self->mt_table[i].me_key);
385 }
386
378 PyMem_FREE(self->mt_table); 387 PyMem_FREE(self->mt_table);
379 PyMem_FREE(self); 388 PyMem_FREE(self);
380 } 389 }
381 390
382 STATIC_MEMOTABLE Py_ssize_t 391 STATIC_MEMOTABLE Py_ssize_t
383 PyMemoTable_Size(PyMemoTable *self) 392 PyMemoTable_Size(PyMemoTable *self)
384 { 393 {
385 return self->mt_used; 394 return self->mt_used;
386 } 395 }
387 396
388 STATIC_MEMOTABLE int 397 STATIC_MEMOTABLE int
389 PyMemoTable_Clear(PyMemoTable *self) 398 PyMemoTable_Clear(PyMemoTable *self)
390 { 399 {
400 Py_ssize_t i;
401 for (i = 0; i < self->mt_allocated; i++) {
402 Py_XDECREF(self->mt_table[i].me_key);
403 }
404
391 self->mt_used = 0; 405 self->mt_used = 0;
392 memset(self->mt_table, 0, self->mt_allocated * sizeof(PyMemoEntry)); 406 memset(self->mt_table, 0, self->mt_allocated * sizeof(PyMemoEntry));
393 return 0; 407 return 0;
394 } 408 }
395 409
396 /* Since entries cannot be deleted from this hashtable, _PyMemoTable_Lookup() 410 /* Since entries cannot be deleted from this hashtable, _PyMemoTable_Lookup()
397 can be considerably simpler than dictobject.c's lookdict(). */ 411 can be considerably simpler than dictobject.c's lookdict(). */
398 static PyMemoEntry * 412 static PyMemoEntry *
399 _PyMemoTable_Lookup(PyMemoTable *self, void *key) 413 _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key)
400 { 414 {
401 size_t i; 415 size_t i;
402 size_t perturb; 416 size_t perturb;
403 size_t mask = (size_t)self->mt_mask; 417 size_t mask = (size_t)self->mt_mask;
404 PyMemoEntry *table = self->mt_table; 418 PyMemoEntry *table = self->mt_table;
405 PyMemoEntry *entry; 419 PyMemoEntry *entry;
406 long hash = (long)key >> 3; 420 long hash = (long)key >> 3;
407 421
408 i = hash & mask; 422 i = hash & mask;
409 entry = &table[i]; 423 entry = &table[i];
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 } 484 }
471 } 485 }
472 486
473 /* Deallocate the old table. */ 487 /* Deallocate the old table. */
474 PyMem_FREE(oldtable); 488 PyMem_FREE(oldtable);
475 return 0; 489 return 0;
476 } 490 }
477 491
478 /* Returns NULL on failure, a pointer to the value otherwise. */ 492 /* Returns NULL on failure, a pointer to the value otherwise. */
479 STATIC_MEMOTABLE long * 493 STATIC_MEMOTABLE long *
480 PyMemoTable_Get(PyMemoTable *self, void *key) 494 PyMemoTable_Get(PyMemoTable *self, PyObject *key)
481 { 495 {
482 PyMemoEntry *entry = _PyMemoTable_Lookup(self, key); 496 PyMemoEntry *entry = _PyMemoTable_Lookup(self, key);
483 if (entry->me_key == NULL) 497 if (entry->me_key == NULL)
484 return NULL; 498 return NULL;
485 return &entry->me_value; 499 return &entry->me_value;
486 } 500 }
487 501
488 /* Returns -1 on failure, 0 on success. */ 502 /* Returns -1 on failure, 0 on success. */
489 STATIC_MEMOTABLE int 503 STATIC_MEMOTABLE int
490 PyMemoTable_Set(PyMemoTable *self, void *key, long value) 504 PyMemoTable_Set(PyMemoTable *self, PyObject *key, long value)
491 { 505 {
492 PyMemoEntry *entry; 506 PyMemoEntry *entry;
493 507
494 assert(key != NULL); 508 assert(key != NULL);
495 509
496 entry = _PyMemoTable_Lookup(self, key); 510 entry = _PyMemoTable_Lookup(self, key);
497 if (entry->me_key != NULL) { 511 if (entry->me_key != NULL) {
498 entry->me_value = value; 512 entry->me_value = value;
499 return 0; 513 return 0;
500 } 514 }
515 Py_INCREF(key);
501 entry->me_key = key; 516 entry->me_key = key;
502 entry->me_value = value; 517 entry->me_value = value;
503 self->mt_used++; 518 self->mt_used++;
504 519
505 /* If we added a key, we can safely resize. Otherwise just return! 520 /* If we added a key, we can safely resize. Otherwise just return!
506 * If used >= 2/3 size, adjust size. Normally, this quaduples the size. 521 * If used >= 2/3 size, adjust size. Normally, this quaduples the size.
507 * 522 *
508 * Quadrupling the size improves average table sparseness 523 * Quadrupling the size improves average table sparseness
509 * (reducing collisions) at the cost of some memory. It also halves 524 * (reducing collisions) at the cost of some memory. It also halves
510 * the number of expensive resize operations in a growing memo table. 525 * the number of expensive resize operations in a growing memo table.
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 char *r = PyMem_NEW(char, n+1); 1074 char *r = PyMem_NEW(char, n+1);
1060 if (r == NULL) 1075 if (r == NULL)
1061 return (char*)PyErr_NoMemory(); 1076 return (char*)PyErr_NoMemory();
1062 memcpy(r, s, n); 1077 memcpy(r, s, n);
1063 r[n] = 0; 1078 r[n] = 0;
1064 return r; 1079 return r;
1065 } 1080 }
1066 1081
1067 1082
1068 static int 1083 static int
1069 get(Picklerobject *self, void *id) 1084 get(Picklerobject *self, PyObject *id)
1070 { 1085 {
1071 long *value; 1086 long *value;
1072 char s[30]; 1087 char s[30];
1073 size_t len; 1088 size_t len;
1074 1089
1075 value = PyMemoTable_Get(self->memo, id); 1090 value = PyMemoTable_Get(self->memo, id);
1076 if (value == NULL) { 1091 if (value == NULL) {
1077 » » PyErr_SetObject(PyExc_KeyError, PyLong_FromVoidPtr(id)); 1092 » » PyErr_SetObject(PyExc_KeyError, PyLong_FromVoidPtr((void *)id));
1078 return -1; 1093 return -1;
1079 } 1094 }
1080 1095
1081 self->uses_gets = 1; 1096 self->uses_gets = 1;
1082 if (!self->bin) { 1097 if (!self->bin) {
1083 s[0] = GET; 1098 s[0] = GET;
1084 PyOS_snprintf(s + 1, sizeof(s) - 1, "%ld\n", *value); 1099 PyOS_snprintf(s + 1, sizeof(s) - 1, "%ld\n", *value);
1085 len = strlen(s); 1100 len = strlen(s);
1086 } 1101 }
1087 else { 1102 else {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 { 1137 {
1123 char c_str[30]; 1138 char c_str[30];
1124 int p; 1139 int p;
1125 size_t len; 1140 size_t len;
1126 1141
1127 if (self->fast) 1142 if (self->fast)
1128 return 0; 1143 return 0;
1129 1144
1130 /* PyMemoTable_{Get,Set} doesn't accept null pointers as keys. */ 1145 /* PyMemoTable_{Get,Set} doesn't accept null pointers as keys. */
1131 p = PyMemoTable_Size(self->memo) + 1; 1146 p = PyMemoTable_Size(self->memo) + 1;
1132 » if (PyMemoTable_Set(self->memo, (void *)ob, p) < 0) 1147 » if (PyMemoTable_Set(self->memo, ob, p) < 0)
1133 return -1; 1148 return -1;
1134 1149
1135 if (!self->bin) { 1150 if (!self->bin) {
1136 c_str[0] = PUT; 1151 c_str[0] = PUT;
1137 PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%d\n", p); 1152 PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%d\n", p);
1138 len = strlen(c_str); 1153 len = strlen(c_str);
1139 } 1154 }
1140 else { 1155 else {
1141 if (p >= 256) { 1156 if (p >= 256) {
1142 c_str[0] = LONG_BINPUT; 1157 c_str[0] = LONG_BINPUT;
(...skipping 2344 matching lines...) Expand 10 before | Expand all | Expand 10 after
3487 } 3502 }
3488 else if (PyDict_Check(pymemo)) { 3503 else if (PyDict_Check(pymemo)) {
3489 PyObject *pykey, *pyval; 3504 PyObject *pykey, *pyval;
3490 Py_ssize_t i = 0; 3505 Py_ssize_t i = 0;
3491 3506
3492 if (p->memo != NULL) 3507 if (p->memo != NULL)
3493 PyMemoTable_Del(p->memo); 3508 PyMemoTable_Del(p->memo);
3494 p->memo = PyMemoTable_New(); 3509 p->memo = PyMemoTable_New();
3495 3510
3496 while (PyDict_Next(pymemo, &i, &pykey, &pyval)) { 3511 while (PyDict_Next(pymemo, &i, &pykey, &pyval)) {
3497 » » » long val; 3512 » » » long val = PyLong_AsLong(pyval);
3498 » » » void *key = (void *)PyLong_AsLong(pykey); 3513 » » » if (PyMemoTable_Set(p->memo, pykey, val) < 0)
3499 » » » val = PyLong_AsLong(pyval);
3500 » » » if (PyMemoTable_Set(p->memo, key, val) < 0)
3501 return -1; 3514 return -1;
3502 } 3515 }
3503 3516
3504 return 0; 3517 return 0;
3505 } 3518 }
3506 else { 3519 else {
3507 PyErr_Format(PyExc_TypeError, 3520 PyErr_Format(PyExc_TypeError,
3508 "'memo' attribute must be a PicklerMemoProxy " 3521 "'memo' attribute must be a PicklerMemoProxy "
3509 "object or dict, not %.200s", 3522 "object or dict, not %.200s",
3510 Py_TYPE(pymemo)->tp_name); 3523 Py_TYPE(pymemo)->tp_name);
(...skipping 3032 matching lines...) Expand 10 before | Expand all | Expand 10 after
6543 "1.0", /* Original protocol 0 */ 6556 "1.0", /* Original protocol 0 */
6544 "1.1", /* Protocol 0 + INST */ 6557 "1.1", /* Protocol 0 + INST */
6545 "1.2", /* Original protocol 1 */ 6558 "1.2", /* Original protocol 1 */
6546 "1.3", /* Protocol 1 + BINFLOAT */ 6559 "1.3", /* Protocol 1 + BINFLOAT */
6547 "2.0"); /* Original protocol 2 */ 6560 "2.0"); /* Original protocol 2 */
6548 PyDict_SetItemString(d, "format_version", format_version); 6561 PyDict_SetItemString(d, "format_version", format_version);
6549 PyDict_SetItemString(d, "compatible_formats", compatible_formats); 6562 PyDict_SetItemString(d, "compatible_formats", compatible_formats);
6550 Py_XDECREF(format_version); 6563 Py_XDECREF(format_version);
6551 Py_XDECREF(compatible_formats); 6564 Py_XDECREF(compatible_formats);
6552 } 6565 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld r497