Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/picologging/_picologging.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,8 @@ static int
picologging_clear(PyObject *module)
{
picologging_state *state = get_picologging_state(module);
if (state && state->g_filepathCache) {
delete state->g_filepathCache;
state->g_filepathCache = nullptr;

if (state) {
Py_XDECREF(state->g_filepathCache);
Py_DECREF(state->g_const_CRITICAL);
Py_DECREF(state->g_const_ERROR);
Py_DECREF(state->g_const_WARNING);
Expand Down Expand Up @@ -156,7 +154,7 @@ PyMODINIT_FUNC PyInit__picologging(void)

// Initialize module state
picologging_state *state = get_picologging_state(m);
state->g_filepathCache = new FilepathCache();
state->g_filepathCache = PyDict_New();
state->g_const_CRITICAL = PyUnicode_FromString("CRITICAL");
state->g_const_ERROR = PyUnicode_FromString("ERROR");
state->g_const_WARNING = PyUnicode_FromString("WARNING");
Expand Down
41 changes: 16 additions & 25 deletions src/picologging/filepathcache.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,27 @@

namespace fs = std::filesystem;

const FilepathCacheEntry& FilepathCache::lookup(PyObject* pathname){
/*
* Notes: A vector ended up being significantly faster than an unordered_map,
* even though an unordered_map should probably be used.
* TODO #3 : Cap vector size or decide on a better map type.
*/
Py_hash_t hash = PyObject_Hash(pathname);
for (auto& entry : cache){
if (entry.first == hash){
return entry.second;
}
PyObject* lookup(PyObject* cache, PyObject* pathname){
PyObject* result = PyDict_GetItem(cache, pathname);
if (result != NULL){
return result;
}
FilepathCacheEntry* entry = new FilepathCacheEntry();

fs::path fs_path = fs::path(PyUnicode_AsUTF8(pathname));
PyObject *filename = nullptr, *module = nullptr;
#ifdef WIN32
const wchar_t* filename_wchar = fs_path.filename().c_str();
const wchar_t* modulename = fs_path.stem().c_str();
entry->filename = PyUnicode_FromWideChar(filename_wchar, wcslen(filename_wchar)),
entry->module = PyUnicode_FromWideChar(modulename, wcslen(modulename));
filename = PyUnicode_FromWideChar(filename_wchar, wcslen(filename_wchar)),
module = PyUnicode_FromWideChar(modulename, wcslen(modulename));
#else
entry->filename = PyUnicode_FromString(fs_path.filename().c_str());
entry->module = PyUnicode_FromString(fs_path.stem().c_str());
filename = PyUnicode_FromString(fs_path.filename().c_str());
module = PyUnicode_FromString(fs_path.stem().c_str());
#endif
cache.push_back({hash, *entry});
return *entry;
PyObject *cacheItem = PyTuple_Pack(2, filename, module);
PyDict_SetItem(cache, pathname, cacheItem);
Py_DECREF(cacheItem);
Py_DECREF(filename);
Py_DECREF(module);
return cacheItem;
}

FilepathCache::~FilepathCache(){
for (auto& entry : cache){
Py_CLEAR(entry.second.filename);
Py_CLEAR(entry.second.module);
}
}
14 changes: 1 addition & 13 deletions src/picologging/filepathcache.hxx
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
#include <Python.h>
#include <structmember.h>
#include <cstddef>
#include <vector>

#ifndef PICOLOGGING_FILEPATHCACHE_H
#define PICOLOGGING_FILEPATHCACHE_H

typedef struct {
PyObject* filename;
PyObject* module;
} FilepathCacheEntry;

class FilepathCache {
std::vector<std::pair<Py_hash_t, FilepathCacheEntry>> cache;
public:
const FilepathCacheEntry& lookup(PyObject* filepath);
~FilepathCache();
};

PyObject* lookup(PyObject* cache, PyObject* pathname);
#endif // PICOLOGGING_FILEPATHCACHE_H
6 changes: 3 additions & 3 deletions src/picologging/logrecord.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ LogRecord* LogRecord_create(LogRecord* self, PyObject* name, PyObject* msg, PyOb

#ifdef PICOLOGGING_CACHE_FILEPATH
if (state && state->g_filepathCache != nullptr) {
auto filepath = state->g_filepathCache->lookup(pathname);
self->filename = Py_NewRef(filepath.filename);
self->module = Py_NewRef(filepath.module);
auto filepath = lookup(state->g_filepathCache, pathname);
self->filename = Py_NewRef(PyTuple_GET_ITEM(filepath, 0));
self->module = Py_NewRef(PyTuple_GET_ITEM(filepath, 1));
} else {
// Manual lookup - TODO Raise warning?
fs::path fs_path = fs::path(PyUnicode_AsUTF8(pathname));
Expand Down
2 changes: 1 addition & 1 deletion src/picologging/picologging.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#define PICOLOGGING_H

typedef struct {
FilepathCache* g_filepathCache;
PyObject* g_filepathCache;
PyObject* g_const_CRITICAL;
PyObject* g_const_ERROR;
PyObject* g_const_WARNING;
Expand Down