mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-15 16:45:50 +00:00
Per XLS-0095, we are taking steps to rename ripple(d) to xrpl(d). This change specifically removes all copyright notices referencing Ripple, XRPLF, and certain affiliated contributors upon mutual agreement, so the notice in the LICENSE.md file applies throughout. Copyright notices referencing external contributions remain as-is. Duplicate verbiage is also removed.
139 lines
2.6 KiB
C++
139 lines
2.6 KiB
C++
#ifndef XRPL_BASICS_COUNTEDOBJECT_H_INCLUDED
|
|
#define XRPL_BASICS_COUNTEDOBJECT_H_INCLUDED
|
|
|
|
#include <xrpl/beast/type_name.h>
|
|
|
|
#include <atomic>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace ripple {
|
|
|
|
/** Manages all counted object types. */
|
|
class CountedObjects
|
|
{
|
|
public:
|
|
static CountedObjects&
|
|
getInstance() noexcept;
|
|
|
|
using Entry = std::pair<std::string, int>;
|
|
using List = std::vector<Entry>;
|
|
|
|
List
|
|
getCounts(int minimumThreshold) const;
|
|
|
|
public:
|
|
/** Implementation for @ref CountedObject.
|
|
|
|
@internal
|
|
*/
|
|
class Counter
|
|
{
|
|
public:
|
|
Counter(std::string name) noexcept : name_(std::move(name)), count_(0)
|
|
{
|
|
// Insert ourselves at the front of the lock-free linked list
|
|
CountedObjects& instance = CountedObjects::getInstance();
|
|
Counter* head;
|
|
|
|
do
|
|
{
|
|
head = instance.m_head.load();
|
|
next_ = head;
|
|
} while (instance.m_head.exchange(this) != head);
|
|
|
|
++instance.m_count;
|
|
}
|
|
|
|
~Counter() noexcept = default;
|
|
|
|
int
|
|
increment() noexcept
|
|
{
|
|
return ++count_;
|
|
}
|
|
|
|
int
|
|
decrement() noexcept
|
|
{
|
|
return --count_;
|
|
}
|
|
|
|
int
|
|
getCount() const noexcept
|
|
{
|
|
return count_.load();
|
|
}
|
|
|
|
Counter*
|
|
getNext() const noexcept
|
|
{
|
|
return next_;
|
|
}
|
|
|
|
std::string const&
|
|
getName() const noexcept
|
|
{
|
|
return name_;
|
|
}
|
|
|
|
private:
|
|
std::string const name_;
|
|
std::atomic<int> count_;
|
|
Counter* next_;
|
|
};
|
|
|
|
private:
|
|
CountedObjects() noexcept;
|
|
~CountedObjects() noexcept = default;
|
|
|
|
private:
|
|
std::atomic<int> m_count;
|
|
std::atomic<Counter*> m_head;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
/** Tracks the number of instances of an object.
|
|
|
|
Derived classes have their instances counted automatically. This is used
|
|
for reporting purposes.
|
|
|
|
@ingroup ripple_basics
|
|
*/
|
|
template <class Object>
|
|
class CountedObject
|
|
{
|
|
private:
|
|
static auto&
|
|
getCounter() noexcept
|
|
{
|
|
static CountedObjects::Counter c{beast::type_name<Object>()};
|
|
return c;
|
|
}
|
|
|
|
public:
|
|
CountedObject() noexcept
|
|
{
|
|
getCounter().increment();
|
|
}
|
|
|
|
CountedObject(CountedObject const&) noexcept
|
|
{
|
|
getCounter().increment();
|
|
}
|
|
|
|
CountedObject&
|
|
operator=(CountedObject const&) noexcept = default;
|
|
|
|
~CountedObject() noexcept
|
|
{
|
|
getCounter().decrement();
|
|
}
|
|
};
|
|
|
|
} // namespace ripple
|
|
|
|
#endif
|