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

Delta Between Two Patch Sets: Modules/_functoolsmodule.c

Issue 14373: C implementation of functools.lru_cache
Left Patch Set: Created 4 years, 5 months ago
Right Patch Set: Created 4 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 1
2 #include "Python.h" 2 #include "Python.h"
3 #include "structmember.h" 3 #include "structmember.h"
4 4
5 /* _functools module written and maintained 5 /* _functools module written and maintained
6 by Hye-Shik Chang <perky@FreeBSD.org> 6 by Hye-Shik Chang <perky@FreeBSD.org>
7 with adaptations by Raymond Hettinger <python@rcn.com> 7 with adaptations by Raymond Hettinger <python@rcn.com>
8 Copyright (c) 2004, 2005, 2006 Python Software Foundation. 8 Copyright (c) 2004, 2005, 2006 Python Software Foundation.
9 All rights reserved. 9 All rights reserved.
10 */ 10 */
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 } lru_cache_object; 674 } lru_cache_object;
675 675
676 static PyTypeObject lru_cache_type; 676 static PyTypeObject lru_cache_type;
677 677
678 static PyObject * 678 static PyObject *
679 lru_cache_make_key(PyObject *args, PyObject *kwds, int typed) 679 lru_cache_make_key(PyObject *args, PyObject *kwds, int typed)
680 { 680 {
681 PyObject *key, *sorted_items; 681 PyObject *key, *sorted_items;
682 Py_ssize_t key_size, pos, key_pos; 682 Py_ssize_t key_size, pos, key_pos;
683 683
684 /* short path, key will match args anyway, which is a tuple */
685 if (!typed && !kwds) {
686 Py_INCREF(args);
687 return args;
688 }
689
684 if (kwds && PyDict_Size(kwds) > 0) { 690 if (kwds && PyDict_Size(kwds) > 0) {
685 sorted_items = PyDict_Items(kwds); 691 sorted_items = PyDict_Items(kwds);
686 if (!sorted_items) 692 if (!sorted_items)
687 return NULL; 693 return NULL;
688 if (PyList_Sort(sorted_items) < 0) { 694 if (PyList_Sort(sorted_items) < 0) {
689 Py_DECREF(sorted_items); 695 Py_DECREF(sorted_items);
690 return NULL; 696 return NULL;
691 } 697 }
692 } else 698 } else
693 sorted_items = NULL; 699 sorted_items = NULL;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 Py_INCREF(result); /* for return */ 892 Py_INCREF(result); /* for return */
887 self->full = (PyDict_Size(self->cache) >= self->maxsize); 893 self->full = (PyDict_Size(self->cache) >= self->maxsize);
888 } 894 }
889 self->misses++; 895 self->misses++;
890 return result; 896 return result;
891 } 897 }
892 898
893 static PyObject * 899 static PyObject *
894 lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw) 900 lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
895 { 901 {
896 PyObject *func, *maxsize_O, *cache_info_type; 902 PyObject *func, *maxsize_O, *cache_info_type, *cachedict;
897 int typed; 903 int typed;
898 lru_cache_object *obj; 904 lru_cache_object *obj;
899 Py_ssize_t maxsize; 905 Py_ssize_t maxsize;
900 PyObject *(*wrapper)(lru_cache_object *, PyObject *, PyObject *); 906 PyObject *(*wrapper)(lru_cache_object *, PyObject *, PyObject *);
901 static char *keywords[] = {"user_function", "maxsize", "typed", 907 static char *keywords[] = {"user_function", "maxsize", "typed",
902 "cache_info_type", NULL}; 908 "cache_info_type", NULL};
903 909
904 if (!PyArg_ParseTupleAndKeywords(args, kw, "OOpO:lru_cache", keywords, 910 if (!PyArg_ParseTupleAndKeywords(args, kw, "OOpO:lru_cache", keywords,
905 &func, &maxsize_O, &typed, 911 &func, &maxsize_O, &typed,
906 &cache_info_type)) { 912 &cache_info_type)) {
(...skipping 17 matching lines...) Expand all
924 return NULL; 930 return NULL;
925 if (maxsize == 0) 931 if (maxsize == 0)
926 wrapper = uncached_lru_cache_wrapper; 932 wrapper = uncached_lru_cache_wrapper;
927 else 933 else
928 wrapper = bounded_lru_cache_wrapper; 934 wrapper = bounded_lru_cache_wrapper;
929 } else { 935 } else {
930 PyErr_SetString(PyExc_TypeError, "maxsize should be integer or None"); 936 PyErr_SetString(PyExc_TypeError, "maxsize should be integer or None");
931 return NULL; 937 return NULL;
932 } 938 }
933 939
940 if (!(cachedict = PyDict_New()))
941 return NULL;
942
934 obj = (lru_cache_object *)type->tp_alloc(type, 0); 943 obj = (lru_cache_object *)type->tp_alloc(type, 0);
935 if (obj == NULL) 944 if (obj == NULL) {
936 return NULL; 945 Py_DECREF(cachedict);
937 946 return NULL;
938 if (!(obj->cache = PyDict_New())) { 947 }
939 Py_DECREF(obj); 948
940 return NULL; 949 obj->cache = cachedict;
941 }
942
943 obj->root.prev = &obj->root; 950 obj->root.prev = &obj->root;
944 obj->root.next = &obj->root; 951 obj->root.next = &obj->root;
945 obj->maxsize = maxsize; 952 obj->maxsize = maxsize;
946 Py_INCREF(maxsize_O); 953 Py_INCREF(maxsize_O);
947 obj->maxsize_O = maxsize_O; 954 obj->maxsize_O = maxsize_O;
948 Py_INCREF(func); 955 Py_INCREF(func);
949 obj->func = func; 956 obj->func = func;
950 obj->wrapper = wrapper; 957 obj->wrapper = wrapper;
951 obj->misses = obj->hits = 0; 958 obj->misses = obj->hits = 0;
952 obj->typed = typed; 959 obj->typed = typed;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 Py_XDECREF(obj->dict); 995 Py_XDECREF(obj->dict);
989 Py_XDECREF(obj->cache_info_type); 996 Py_XDECREF(obj->cache_info_type);
990 lru_cache_clear_list(list); 997 lru_cache_clear_list(list);
991 Py_TYPE(obj)->tp_free(obj); 998 Py_TYPE(obj)->tp_free(obj);
992 } 999 }
993 1000
994 static PyObject * 1001 static PyObject *
995 lru_cache_call(lru_cache_object *self, PyObject *args, PyObject *kwds) 1002 lru_cache_call(lru_cache_object *self, PyObject *args, PyObject *kwds)
996 { 1003 {
997 return self->wrapper(self, args, kwds); 1004 return self->wrapper(self, args, kwds);
1005 }
1006
1007 static PyObject *
1008 lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1009 {
1010 if (obj == Py_None || obj == NULL) {
1011 Py_INCREF(self);
1012 return self;
1013 }
1014 return PyMethod_New(self, obj);
998 } 1015 }
999 1016
1000 static PyObject * 1017 static PyObject *
1001 lru_cache_cache_info(lru_cache_object *self, PyObject *unused) 1018 lru_cache_cache_info(lru_cache_object *self, PyObject *unused)
1002 { 1019 {
1003 return PyObject_CallFunction(self->cache_info_type, "nnOn", 1020 return PyObject_CallFunction(self->cache_info_type, "nnOn",
1004 self->hits, self->misses, self->maxsize_O, 1021 self->hits, self->misses, self->maxsize_O,
1005 PyDict_Size(self->cache)); 1022 PyDict_Size(self->cache));
1006 } 1023 }
1007 1024
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 (inquiry)lru_cache_tp_clear, /* tp_clear */ 1119 (inquiry)lru_cache_tp_clear, /* tp_clear */
1103 0, /* tp_richcompare */ 1120 0, /* tp_richcompare */
1104 0, /* tp_weaklistoffset */ 1121 0, /* tp_weaklistoffset */
1105 0, /* tp_iter */ 1122 0, /* tp_iter */
1106 0, /* tp_iternext */ 1123 0, /* tp_iternext */
1107 lru_cache_methods, /* tp_methods */ 1124 lru_cache_methods, /* tp_methods */
1108 0, /* tp_members */ 1125 0, /* tp_members */
1109 lru_cache_getsetlist, /* tp_getset */ 1126 lru_cache_getsetlist, /* tp_getset */
1110 0, /* tp_base */ 1127 0, /* tp_base */
1111 0, /* tp_dict */ 1128 0, /* tp_dict */
1112 0, /* tp_descr_get */ 1129 lru_cache_descr_get, /* tp_descr_get */
1113 0, /* tp_descr_set */ 1130 0, /* tp_descr_set */
1114 offsetof(lru_cache_object, dict), /* tp_dictoffset */ 1131 offsetof(lru_cache_object, dict), /* tp_dictoffset */
1115 0, /* tp_init */ 1132 0, /* tp_init */
1116 0, /* tp_alloc */ 1133 0, /* tp_alloc */
1117 lru_cache_new, /* tp_new */ 1134 lru_cache_new, /* tp_new */
1118 }; 1135 };
1119 1136
1120 /* module level code ********************************************************/ 1137 /* module level code ********************************************************/
1121 1138
1122 PyDoc_STRVAR(module_doc, 1139 PyDoc_STRVAR(module_doc,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 Py_DECREF(m); 1191 Py_DECREF(m);
1175 return NULL; 1192 return NULL;
1176 } 1193 }
1177 name = strchr(typelist[i]->tp_name, '.'); 1194 name = strchr(typelist[i]->tp_name, '.');
1178 assert (name != NULL); 1195 assert (name != NULL);
1179 Py_INCREF(typelist[i]); 1196 Py_INCREF(typelist[i]);
1180 PyModule_AddObject(m, name+1, (PyObject *)typelist[i]); 1197 PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
1181 } 1198 }
1182 return m; 1199 return m;
1183 } 1200 }
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+