Files
rippled/include/xrpl/basics/CountedObject.h
2025-11-10 11:49:19 -05:00

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 xrpl {
/** 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 xrpl
#endif