12 #ifndef ROOT_TThreadedObject 13 #define ROOT_TThreadedObject 35 namespace TThreadedObjectUtils {
39 static unsigned fgTThreadedObjectIndex = 0;
40 return fgTThreadedObjectIndex++;
43 template<typename T, bool ISHISTO = std::is_base_of<TH1,T>::value>
53 obj->SetDirectory(
nullptr);
60 template<class T, bool isCopyConstructible = std::is_copy_constructible<T>::value>
80 clone = (
T*)obj->Clone();
82 clone = (
T*)obj->Clone();
88 template<class T, bool ISHISTO = std::is_base_of<TH1,T>::value>
90 static std::vector<TDirectory*>
Create(
unsigned maxSlots) {
91 std::string dirName =
"__TThreaded_dir_";
93 std::vector<TDirectory*> dirs;
94 dirs.reserve(maxSlots);
95 for (
unsigned i=0; i< maxSlots;++i) {
96 auto dir =
gROOT->mkdir((dirName+std::to_string(i)).c_str());
97 dirs.emplace_back(dir);
105 static std::vector<TDirectory*>
Create(
unsigned maxSlots) {
106 std::vector<TDirectory*> dirs(maxSlots,
nullptr);
114 namespace TThreadedObjectUtils {
117 using MergeFunctionType = std::function<void(std::shared_ptr<T>, std::vector<std::shared_ptr<T>>&)>;
120 void MergeTObjects(std::shared_ptr<T> target, std::vector<std::shared_ptr<T>> &objs)
125 for (
auto obj : objs) {
126 if (obj && obj != target) objTList.
Add(obj.get());
128 target->Merge(&objTList);
155 template<
class ...ARGS>
170 Warning(
"TThreadedObject::GetAtSlot",
"Maximum number of slots reached.");
239 Warning(
"TThreadedObject::Merge",
"This object was already merged. Returning the previous result.");
254 Warning(
"TThreadedObject::SnapshotMerge",
"This object was already merged. Returning the previous result.");
258 std::shared_ptr<T> targetPtrShared(targetPtr, [](
T *) {});
260 return std::unique_ptr<T>(targetPtr);
275 const auto thisThreadID = std::this_thread::get_id();
280 if (thisSlotNumIt !=
fThrIDSlotMap.end())
return thisSlotNumIt->second;
302 auto model = ((std::unique_ptr<T>*)(val))->
get();
303 std::ostringstream ret;
304 ret <<
"A wrapper to make object instances thread private, lazily. " std::shared_ptr< T > GetAtSlotUnchecked(unsigned i) const
Access a particular slot which corresponds to a single thread.
bool fIsMerged
Remember if the objects have been merged already.
T * operator->()
Access the wrapped object and allow to call its methods.
Namespace for new ROOT classes and functions.
TThreadedObject(const TThreadedObject &)=delete
A wrapper to make object instances thread private, lazily.
A spin mutex class which respects the STL interface for mutexes.
std::unique_ptr< T > fModel
Use to store a "model" of the object.
std::shared_ptr< T > Get()
Access the pointer corresponding to the current slot.
void SetAtSlot(unsigned i, std::shared_ptr< T > v)
Set the value of a particular slot.
std::vector< std::shared_ptr< T > > fObjPointers
A pointer per thread is kept.
std::map< std::thread::id, unsigned > fThrIDSlotMap
A mapping between the thread IDs and the slots.
static std::vector< TDirectory * > Create(unsigned maxSlots)
T * GetAtSlotRaw(unsigned i) const
Access a particular slot which corresponds to a single thread.
std::string printValue(const TDatime *val)
Print a TDatime at the prompt.
unsigned GetThisSlotNumber()
Get the slot number for this threadID.
unsigned fCurrMaxSlotIndex
The maximum slot index.
static unsigned fgMaxSlots
The maximum number of processing slots (distinct threads) which the instances can manage...
static T * Detach(T *obj)
std::shared_ptr< T > GetAtSlot(unsigned i)
Access a particular processing slot.
void Warning(const char *location, const char *msgfmt,...)
void MergeTObjects(std::shared_ptr< T > target, std::vector< std::shared_ptr< T >> &objs)
Merge TObjects.
static T * Clone(const T *obj, TDirectory *d=nullptr)
static T * Detach(T *obj)
Describe directory structure in memory.
Print a TSeq at the prompt:
std::shared_ptr< T > Merge(TThreadedObjectUtils::MergeFunctionType< T > mergeFunction=TThreadedObjectUtils::MergeTObjects< T >)
Merge all the thread private objects.
std::vector< TDirectory * > fDirectories
A TDirectory per thread is kept.
ROOT::TSpinMutex fThrIDSlotMutex
Mutex to protect the ID-slot map access.
std::function< void(std::shared_ptr< T >, std::vector< std::shared_ptr< T > > &)> MergeFunctionType
virtual void Add(TObject *obj)
static T * Clone(const T *obj, TDirectory *d=nullptr)
unsigned GetTThreadedObjectIndex()
Get the unique index identifying a TThreadedObject.
TThreadedObject(ARGS &&... args)
Construct the TThreaded object and the "model" of the thread private objects.
Return a copy of the object or a "Clone" if the copy constructor is not implemented.
std::unique_ptr< T > SnapshotMerge(TThreadedObjectUtils::MergeFunctionType< T > mergeFunction=TThreadedObjectUtils::MergeTObjects< T >)
Merge all the thread private objects.
static std::vector< TDirectory * > Create(unsigned maxSlots)