lru-dict
Advanced tools
| Metadata-Version: 1.1 | ||
| Name: lru-dict | ||
| Version: 1.1.5 | ||
| Version: 1.1.6 | ||
| Summary: An Dict like LRU container. | ||
@@ -80,2 +80,23 @@ Home-page: https://github.com/amitdev/lru-dict | ||
| def evicted(key, value): | ||
| print "removing: %s, %s" % (key, value) | ||
| l = LRU(1, callback=evicted) | ||
| l[1] = '1' | ||
| l[2] = '2' | ||
| # callback would print removing: 1, 1 | ||
| l[2] = '3' | ||
| # doesn't call the evicted callback | ||
| print l.items() | ||
| # would print [(2, '3')] | ||
| del l[2] | ||
| # doesn't call the evicted callback | ||
| print l.items() | ||
| # would print [] | ||
| Install | ||
@@ -82,0 +103,0 @@ ======= |
+61
-3
@@ -130,4 +130,29 @@ #include <Python.h> | ||
| Py_ssize_t misses; | ||
| PyObject *callback; | ||
| } LRU; | ||
| static PyObject * | ||
| set_callback(LRU *self, PyObject *args) | ||
| { | ||
| PyObject *result = NULL; | ||
| PyObject *temp; | ||
| if (PyArg_ParseTuple(args, "O:set_callback", &temp)) { | ||
| if (temp == Py_None) { | ||
| Py_XDECREF(self->callback); | ||
| self->callback = NULL; | ||
| } else if (!PyCallable_Check(temp)) { | ||
| PyErr_SetString(PyExc_TypeError, "parameter must be callable"); | ||
| return NULL; | ||
| } else { | ||
| Py_XINCREF(temp); /* Add a reference to new callback */ | ||
| Py_XDECREF(self->callback); /* Dispose of previous callback */ | ||
| self->callback = temp; /* Remember new callback */ | ||
| } | ||
| Py_RETURN_NONE; | ||
| } | ||
| return result; | ||
| } | ||
| static void | ||
@@ -170,2 +195,4 @@ lru_remove_node(LRU *self, Node* node) | ||
| { | ||
| PyObject *arglist; | ||
| PyObject *result; | ||
| Node* n = self->last; | ||
@@ -176,2 +203,10 @@ | ||
| if (self->callback) { | ||
| arglist = Py_BuildValue("OO", n->key, n->value); | ||
| result = PyObject_CallObject(self->callback, arglist); | ||
| Py_XDECREF(result); | ||
| Py_DECREF(arglist); | ||
| } | ||
| lru_remove_node(self, n); | ||
@@ -407,2 +442,8 @@ PUT_NODE(self->dict, n->key, NULL); | ||
| static PyObject * | ||
| LRU_set_callback(LRU *self, PyObject *args) | ||
| { | ||
| return set_callback(self, args); | ||
| } | ||
| static PyObject * | ||
| get_item(Node *node) | ||
@@ -514,2 +555,4 @@ { | ||
| PyDoc_STR("L.update() -> update value for key in LRU")}, | ||
| {"set_callback", (PyCFunction)LRU_set_callback, METH_VARARGS, | ||
| PyDoc_STR("L.set_callback(callback) -> set a callback to call when an item is evicted.")}, | ||
| {NULL, NULL}, | ||
@@ -527,5 +570,18 @@ }; | ||
| { | ||
| if (!PyArg_ParseTuple(args, "n", &self->size)) { | ||
| static char *kwlist[] = {"size", "callback", NULL}; | ||
| PyObject *callback = NULL; | ||
| self->callback = NULL; | ||
| if (!PyArg_ParseTupleAndKeywords(args, kwds, "n|O", kwlist, &self->size, &callback)) { | ||
| return -1; | ||
| } | ||
| if (callback && callback != Py_None) { | ||
| if (!PyCallable_Check(callback)) { | ||
| PyErr_SetString(PyExc_TypeError, "parameter must be callable"); | ||
| return -1; | ||
| } | ||
| Py_XINCREF(callback); | ||
| self->callback = callback; | ||
| } | ||
| if ((Py_ssize_t)self->size <= 0) { | ||
@@ -548,2 +604,3 @@ PyErr_SetString(PyExc_ValueError, "Size should be a positive number"); | ||
| Py_DECREF(self->dict); | ||
| Py_XDECREF(self->callback); | ||
| } | ||
@@ -554,6 +611,7 @@ PyObject_Del((PyObject*)self); | ||
| PyDoc_STRVAR(lru_doc, | ||
| "LRU(size) -> new LRU dict that can store upto size elements\n" | ||
| "LRU(size, callback=None) -> new LRU dict that can store up to size elements\n" | ||
| "An LRU dict behaves like a standard dict, except that it stores only fixed\n" | ||
| "set of elements. Once the size overflows, it evicts least recently used\n" | ||
| "items.\n\n" | ||
| "items. If a callback is set it will call the callback with the evicted key\n" | ||
| " and item.\n\n" | ||
| "Eg:\n" | ||
@@ -560,0 +618,0 @@ ">>> l = LRU(3)\n" |
+22
-1
| Metadata-Version: 1.1 | ||
| Name: lru-dict | ||
| Version: 1.1.5 | ||
| Version: 1.1.6 | ||
| Summary: An Dict like LRU container. | ||
@@ -80,2 +80,23 @@ Home-page: https://github.com/amitdev/lru-dict | ||
| def evicted(key, value): | ||
| print "removing: %s, %s" % (key, value) | ||
| l = LRU(1, callback=evicted) | ||
| l[1] = '1' | ||
| l[2] = '2' | ||
| # callback would print removing: 1, 1 | ||
| l[2] = '3' | ||
| # doesn't call the evicted callback | ||
| print l.items() | ||
| # would print [(2, '3')] | ||
| del l[2] | ||
| # doesn't call the evicted callback | ||
| print l.items() | ||
| # would print [] | ||
| Install | ||
@@ -82,0 +103,0 @@ ======= |
+21
-0
@@ -72,2 +72,23 @@ LRU Dict | ||
| def evicted(key, value): | ||
| print "removing: %s, %s" % (key, value) | ||
| l = LRU(1, callback=evicted) | ||
| l[1] = '1' | ||
| l[2] = '2' | ||
| # callback would print removing: 1, 1 | ||
| l[2] = '3' | ||
| # doesn't call the evicted callback | ||
| print l.items() | ||
| # would print [(2, '3')] | ||
| del l[2] | ||
| # doesn't call the evicted callback | ||
| print l.items() | ||
| # would print [] | ||
| Install | ||
@@ -74,0 +95,0 @@ ======= |
+1
-1
@@ -7,3 +7,3 @@ from setuptools import setup, Extension | ||
| setup (name = 'lru-dict', | ||
| version = '1.1.5', | ||
| version = '1.1.6', | ||
| description = 'An Dict like LRU container.', | ||
@@ -10,0 +10,0 @@ long_description = open('README.rst').read(), |
+48
-0
@@ -274,3 +274,51 @@ import gc | ||
| def test_callback(self): | ||
| counter = [0] | ||
| first_key = 'a' | ||
| first_value = 1 | ||
| def callback(key, value): | ||
| self.assertEqual(key, first_key) | ||
| self.assertEqual(value, first_value) | ||
| counter[0] += 1 | ||
| l = LRU(1, callback=callback) | ||
| l[first_key] = first_value | ||
| l['b'] = 1 # test calling the callback | ||
| self.assertEqual(counter[0], 1) | ||
| self.assertEqual(l.keys(), ['b']) | ||
| l['b'] = 2 # doesn't call callback | ||
| self.assertEqual(counter[0], 1) | ||
| self.assertEqual(l.keys(), ['b']) | ||
| self.assertEqual(l.values(), [2]) | ||
| l = LRU(1, callback=callback) | ||
| l[first_key] = first_value | ||
| l.set_callback(None) | ||
| l['c'] = 1 # doesn't call callback | ||
| self.assertEqual(counter[0], 1) | ||
| self.assertEqual(l.keys(), ['c']) | ||
| l.set_callback(callback) | ||
| del l['c'] # doesn't call callback | ||
| self.assertEqual(counter[0], 1) | ||
| self.assertEqual(l.keys(), []) | ||
| l = LRU(2, callback=callback) | ||
| l['a'] = 1 # test calling the callback | ||
| l['b'] = 2 # test calling the callback | ||
| self.assertEqual(counter[0], 1) | ||
| self.assertEqual(l.keys(), ['b', 'a']) | ||
| l.set_size(1) | ||
| self.assertEqual(counter[0], 2) # callback invoked | ||
| self.assertEqual(l.keys(), ['b']) | ||
| if __name__ == '__main__': | ||
| unittest.main() |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
44561
11.79%296
13.41%