diff --git a/core/cache.c b/core/cache.c index d4e89214..99e0c6ee 100644 --- a/core/cache.c +++ b/core/cache.c @@ -204,6 +204,7 @@ static void uwsgi_cache_add_items(struct uwsgi_cache *uc) { next: usl = usl->next; } + } static void uwsgi_cache_load_files(struct uwsgi_cache *uc) { @@ -1920,3 +1921,24 @@ void uwsgi_cache_setup_nodes(struct uwsgi_cache *uc) { } } +struct uwsgi_cache_item *uwsgi_cache_keys(struct uwsgi_cache *uc, uint64_t *pos, struct uwsgi_cache_item **uci) { + + // security check + if (*pos >= uc->hashsize) return NULL; + // iterate hashtable + uint64_t orig_pos = *pos; + for(;*poshashsize;(*pos)++) { + // get the cache slot + uint64_t slot = uc->hashtable[*pos]; + if (*pos == orig_pos && *uci) { + slot = (*uci)->next; + } + if (slot == 0) continue; + + *uci = cache_item(slot); + return *uci; + } + + (*pos)++; + return NULL; +} diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index 67c1d796..c4442b10 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -3109,6 +3109,35 @@ PyObject *py_uwsgi_cache_num(PyObject * self, PyObject * args) { } +PyObject *py_uwsgi_cache_keys(PyObject * self, PyObject * args) { + char *cache = NULL; + struct uwsgi_cache_item *uci = NULL; + uint64_t pos = 0; + + if (!PyArg_ParseTuple(args, "|s:cache_keys", &cache)) { + return NULL; + } + + struct uwsgi_cache *uc = uwsgi_cache_by_name(cache); + if (!uc) { + return PyErr_Format(PyExc_ValueError, "no local uWSGI cache available"); + } + + PyObject *l = PyList_New(0); + + uwsgi_rlock(uc->lock); + for(;;) { + uci = uwsgi_cache_keys(uc, &pos, &uci); + if (!uci) break; + PyObject *ci = PyString_FromStringAndSize(uci->key, uci->keysize); + PyList_Append(l, ci); + Py_DECREF(ci); + } + uwsgi_rwunlock(uc->lock); + return l; +} + + static PyMethodDef uwsgi_cache_methods[] = { {"cache_get", py_uwsgi_cache_get, METH_VARARGS, ""}, {"cache_set", py_uwsgi_cache_set, METH_VARARGS, ""}, @@ -3121,6 +3150,7 @@ static PyMethodDef uwsgi_cache_methods[] = { {"cache_mul", py_uwsgi_cache_mul, METH_VARARGS, ""}, {"cache_div", py_uwsgi_cache_div, METH_VARARGS, ""}, {"cache_num", py_uwsgi_cache_num, METH_VARARGS, ""}, + {"cache_keys", py_uwsgi_cache_keys, METH_VARARGS, ""}, {NULL, NULL}, }; diff --git a/uwsgi.h b/uwsgi.h index 531daf2e..64114683 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -4150,6 +4150,8 @@ void uwsgi_fsmon_setup(); void uwsgi_exit(int) __attribute__ ((__noreturn__)); void uwsgi_fallback_config(); +struct uwsgi_cache_item *uwsgi_cache_keys(struct uwsgi_cache *, uint64_t *, struct uwsgi_cache_item **); + #ifdef __cplusplus } #endif