Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce ref/deref operations by introducing swap() functions. #433

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 15 additions & 18 deletions taglib/toolkit/tbytevector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,13 +527,13 @@ ByteVector::~ByteVector()

ByteVector &ByteVector::setData(const char *s, uint length)
{
*this = ByteVector(s, length);
ByteVector(s, length).swap(*this);
return *this;
}

ByteVector &ByteVector::setData(const char *data)
{
*this = ByteVector(data);
ByteVector(data).swap(*this);
return *this;
}

Expand Down Expand Up @@ -675,8 +675,7 @@ int ByteVector::endsWithPartialMatch(const ByteVector &pattern) const

ByteVector &ByteVector::append(const ByteVector &v)
{
if(v.d->length != 0)
{
if(!v.isEmpty()) {
detach();

uint originalSize = size();
Expand All @@ -689,7 +688,7 @@ ByteVector &ByteVector::append(const ByteVector &v)

ByteVector &ByteVector::clear()
{
*this = ByteVector();
ByteVector().swap(*this);
return *this;
}

Expand Down Expand Up @@ -889,14 +888,14 @@ bool ByteVector::operator<(const ByteVector &v) const
{
const int result = ::memcmp(data(), v.data(), std::min(size(), v.size()));
if(result != 0)
return result < 0;
return (result < 0);
else
return size() < v.size();
return (size() < v.size());
}

bool ByteVector::operator>(const ByteVector &v) const
{
return v < *this;
return (v < *this);
}

ByteVector ByteVector::operator+(const ByteVector &v) const
Expand All @@ -908,29 +907,27 @@ ByteVector ByteVector::operator+(const ByteVector &v) const

ByteVector &ByteVector::operator=(const ByteVector &v)
{
if(&v == this)
return *this;

if(d->deref())
delete d;

d = v.d;
d->ref();
ByteVector(v).swap(*this);
return *this;
}

ByteVector &ByteVector::operator=(char c)
{
*this = ByteVector(c);
ByteVector(c).swap(*this);
return *this;
}

ByteVector &ByteVector::operator=(const char *data)
{
*this = ByteVector(data);
ByteVector(data).swap(*this);
return *this;
}

void ByteVector::swap(ByteVector &v)
{
std::swap(d, v.d);
}

ByteVector ByteVector::toHex() const
{
ByteVector encoded(size() * 2);
Expand Down
5 changes: 5 additions & 0 deletions taglib/toolkit/tbytevector.h
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,11 @@ namespace TagLib {
*/
ByteVector &operator=(const char *data);

/*!
* Exchanges the content of the ByteVector by the content of \a v.
*/
void swap(ByteVector &v);

/*!
* A static, empty ByteVector which is convenient and fast (since returning
* an empty or "null" value does not require instantiating a new ByteVector).
Expand Down
12 changes: 11 additions & 1 deletion taglib/toolkit/tlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,17 @@ namespace TagLib {
const T &operator[](uint i) const;

/*!
* Make a shallow, implicitly shared, copy of \a l. Because this is
* Makes a shallow, implicitly shared, copy of \a l. Because this is
* implicitly shared, this method is lightweight and suitable for
* pass-by-value usage.
*/
List<T> &operator=(const List<T> &l);

/*!
* Exchanges the content of the List by the content of \a l.
*/
void swap(List<T> &l);

/*!
* Compares this list with \a l and returns true if all of the elements are
* the same.
Expand All @@ -233,6 +238,11 @@ namespace TagLib {
bool operator!=(const List<T> &l) const;

protected:
/*!
* Makes a deep copy of \a l.
*/
List(const std::list<T> &l);

/*
* If this List is being shared via implicit sharing, do a deep copy of the
* data and separate from the shared members. This should be called by all
Expand Down
52 changes: 26 additions & 26 deletions taglib/toolkit/tlist.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,14 @@ public:
////////////////////////////////////////////////////////////////////////////////

template <class T>
List<T>::List()
List<T>::List() :
d(new ListPrivate<T>())
{
d = new ListPrivate<T>;
}

template <class T>
List<T>::List(const List<T> &l) : d(l.d)
List<T>::List(const List<T> &l) :
d(l.d)
{
d->ref();
}
Expand Down Expand Up @@ -188,8 +189,7 @@ List<T> &List<T>::prepend(const List<T> &l)
template <class T>
List<T> &List<T>::clear()
{
detach();
d->clear();
List<T>().swap(*this);
return *this;
}

Expand Down Expand Up @@ -221,7 +221,7 @@ typename List<T>::ConstIterator List<T>::find(const T &value) const
template <class T>
bool List<T>::contains(const T &value) const
{
return std::find(d->list.begin(), d->list.end(), value) != d->list.end();
return (std::find(d->list.begin(), d->list.end(), value) != d->list.end());
}

template <class T>
Expand Down Expand Up @@ -266,60 +266,60 @@ template <class T>
T &List<T>::operator[](uint i)
{
Iterator it = d->list.begin();

for(uint j = 0; j < i; j++)
++it;

std::advance(it, i);
return *it;
}

template <class T>
const T &List<T>::operator[](uint i) const
{
ConstIterator it = d->list.begin();

for(uint j = 0; j < i; j++)
++it;

std::advance(it, i);
return *it;
}

template <class T>
List<T> &List<T>::operator=(const List<T> &l)
{
if(&l == this)
return *this;
if(d != l.d)
List<T>(l).swap(*this);

if(d->deref())
delete d;
d = l.d;
d->ref();
return *this;
}

template <class T>
void List<T>::swap(List<T> &l)
{
std::swap(d, l.d);
}

template <class T>
bool List<T>::operator==(const List<T> &l) const
{
return d->list == l.d->list;
return (d == l.d || d->list == l.d->list);
}

template <class T>
bool List<T>::operator!=(const List<T> &l) const
{
return d->list != l.d->list;
return !(*this == l);
}

////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////

template <class T>
List<T>::List(const std::list<T> &l) :
d(new ListPrivate<T>(l))
{
}

template <class T>
void List<T>::detach()
{
if(d->count() > 1) {
d->deref();
d = new ListPrivate<T>(d->list);
}
if(d->count() > 1)
List<T>(d->list).swap(*this);
}

} // namespace TagLib
14 changes: 14 additions & 0 deletions taglib/toolkit/tmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,21 @@ namespace TagLib {
*/
Map<Key, T> &operator=(const Map<Key, T> &m);

/*!
* Exchanges the content of the Map by the content of \a m.
*/
void swap(Map<Key, T> &m);

protected:
/*!
* Makes a deep copy of \a m.
*/
#ifdef WANT_CLASS_INSTANTIATION_OF_MAP
Map(const std::map<class Key, class T> &m);
#else
Map(const std::map<Key, T> &m);
#endif

/*
* If this List is being shared via implicit sharing, do a deep copy of the
* data and separate from the shared members. This should be called by all
Expand Down
54 changes: 37 additions & 17 deletions taglib/toolkit/tmap.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,24 @@ class Map<Key, T>::MapPrivate : public RefCounterOld
{
public:
MapPrivate() : RefCounterOld() {}

#ifdef WANT_CLASS_INSTANTIATION_OF_MAP

MapPrivate(const std::map<class KeyP, class TP>& m) : RefCounterOld(), map(m) {}
std::map<class KeyP, class TP> map;

#else

MapPrivate(const std::map<KeyP, TP>& m) : RefCounterOld(), map(m) {}
std::map<KeyP, TP> map;

#endif
};

template <class Key, class T>
Map<Key, T>::Map()
Map<Key, T>::Map() :
d(new MapPrivate<Key, T>())
{
d = new MapPrivate<Key, T>;
}

template <class Key, class T>
Expand Down Expand Up @@ -103,8 +108,7 @@ Map<Key, T> &Map<Key, T>::insert(const Key &key, const T &value)
template <class Key, class T>
Map<Key, T> &Map<Key, T>::clear()
{
detach();
d->map.clear();
Map<Key, T>().swap(*this);
return *this;
}

Expand Down Expand Up @@ -145,9 +149,7 @@ template <class Key, class T>
Map<Key, T> &Map<Key,T>::erase(const Key &key)
{
detach();
Iterator it = d->map.find(key);
if(it != d->map.end())
d->map.erase(it);
d->map.erase(key);
return *this;
}

Expand All @@ -173,27 +175,45 @@ T &Map<Key, T>::operator[](const Key &key)
template <class Key, class T>
Map<Key, T> &Map<Key, T>::operator=(const Map<Key, T> &m)
{
if(&m == this)
return *this;
if(d != m.d)
Map<Key, T>(m).swap(*this);

if(d->deref())
delete(d);
d = m.d;
d->ref();
return *this;
}

template <class Key, class T>
void Map<Key, T>::swap(Map<Key, T> &m)
{
std::swap(d, m.d);
}

////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////

#ifdef WANT_CLASS_INSTANTIATION_OF_MAP

template <class Key, class T>
Map<Key, T>::Map(const std::map<class Key, class T> &m) :
d(new MapPrivate<Key, T>(m))
{
}

#else

template <class Key, class T>
Map<Key, T>::Map(const std::map<Key, T> &m) :
d(new MapPrivate<Key, T>(m))
{
}

#endif

template <class Key, class T>
void Map<Key, T>::detach()
{
if(d->count() > 1) {
d->deref();
d = new MapPrivate<Key, T>(d->map);
}
if(d->count() > 1)
Map<Key, T>(d->map).swap(*this);
}

} // namespace TagLib