From 22bed1fb96a37bdf9d032a801f5577f81832fe76 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Wed, 1 Jun 2011 10:25:04 -0300 Subject: optimized keepreference function. Reviewer: Marcelo Lira Luciano Wolf --- libshiboken/basewrapper.cpp | 42 ++++++++++++++++++++++++++---------------- libshiboken/basewrapper_p.h | 2 +- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp index 8dc931727..25307ac48 100644 --- a/libshiboken/basewrapper.cpp +++ b/libshiboken/basewrapper.cpp @@ -320,7 +320,7 @@ PyObject* SbkObjectTpNew(PyTypeObject* subtype, PyObject*, PyObject*) namespace Shiboken { -static void decRefPyObjectList(const std::list &pyObj); +static void decRefPyObjectList(const std::list &pyObj, PyObject* skip = 0); void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visitor) { @@ -475,11 +475,12 @@ std::list splitPyObject(PyObject* pyObj) return result; } -static void decRefPyObjectList(const std::list& lst) +static void decRefPyObjectList(const std::list& lst, PyObject *skip) { - std::list::const_iterator iter = lst.begin(); + std::list::const_iterator iter = lst.begin(); while(iter != lst.end()) { - Py_DECREF(*iter); + if (*iter != skip) + Py_DECREF(*iter); ++iter; } } @@ -1076,22 +1077,31 @@ void keepReference(SbkObject* self, const char* key, PyObject* referredObject, b self->d->referredObjects = new Shiboken::RefCountMap; RefCountMap& refCountMap = *(self->d->referredObjects); - if (!isNone) - Py_INCREF(referredObject); - RefCountMap::iterator iter = refCountMap.find(key); - if (!append && (iter != refCountMap.end())) { - decRefPyObjectList(iter->second); - refCountMap.erase(iter); + std::list objects; + if (iter != refCountMap.end()) { + objects = (*iter).second; + std::list::const_iterator found = std::find(objects.begin(), objects.end(), referredObject); + + // skip if objects already exists + if (found != objects.end()) + return; } - if (!isNone) { - if (append && (iter != refCountMap.end())) { - refCountMap[key].push_back(reinterpret_cast(referredObject)); + if (append && !isNone) { + refCountMap[key].push_back(referredObject); + Py_INCREF(referredObject); + } else if (!append) { + if (objects.size() > 0) + decRefPyObjectList(objects, isNone ? 0 : referredObject); + if (isNone) { + if (iter != refCountMap.end()) + refCountMap.erase(iter); } else { - std::list new_list; - new_list.push_back(reinterpret_cast(referredObject)); - refCountMap[key] = new_list;; + objects.clear(); + objects.push_back(referredObject); + refCountMap[key] = objects; + Py_INCREF(referredObject); } } } diff --git a/libshiboken/basewrapper_p.h b/libshiboken/basewrapper_p.h index f57dc9ca2..25eb12205 100644 --- a/libshiboken/basewrapper_p.h +++ b/libshiboken/basewrapper_p.h @@ -36,7 +36,7 @@ namespace Shiboken * This mapping associates a method and argument of an wrapper object with the wrapper of * said argument when it needs the binding to help manage its reference counting. */ -typedef std::map > RefCountMap; +typedef std::map > RefCountMap; /// Linked list of SbkBaseWrapper pointers -- cgit v1.2.3