Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:22:26

0001 // Author: Danilo Piparo May 2018
0002 
0003 /*************************************************************************
0004  * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers.               *
0005  * All rights reserved.                                                  *
0006  *                                                                       *
0007  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0008  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0009  *************************************************************************/
0010 
0011 #ifndef ROOT_RConcurrentHashColl
0012 #define ROOT_RConcurrentHashColl
0013 
0014 #include <memory>
0015 #include <vector>
0016 #include "Rtypes.h"
0017 
0018 namespace ROOT {
0019 
0020 class TRWSpinLock;
0021 
0022 namespace Internal {
0023 
0024 struct RHashMap;
0025 using RUidColl = std::vector<Int_t>;
0026 
0027 /// This class is a thread-safe associative collection connecting
0028 /// a 256 bits digest/hash to a collection of uid (integer)
0029 /// This is used in the handling of the StreamerInfo record in TFile.
0030 class RConcurrentHashColl {
0031 private:
0032    mutable std::unique_ptr<RHashMap> fHashMap;
0033    mutable std::unique_ptr<ROOT::TRWSpinLock> fRWLock;
0034 
0035 public:
0036    class HashValue {
0037        friend std::ostream &operator<<(std::ostream &os, const RConcurrentHashColl::HashValue &h);
0038    private:
0039       ULong64_t fDigest[4] = {0, 0, 0, 0};
0040 
0041    public:
0042       HashValue() = default;
0043       HashValue(const char *data, int len);
0044       ULong64_t const *Get() const { return fDigest; }
0045 
0046       /// Return the hash value for this object
0047       size_t Hash() const noexcept {
0048          std::hash<ULong64_t> hasher;
0049          return hasher(fDigest[0]) ^ hasher(fDigest[1])
0050                ^ hasher(fDigest[2]) ^ hasher(fDigest[3]);
0051       }
0052    };
0053 
0054    RConcurrentHashColl();
0055    ~RConcurrentHashColl();
0056 
0057    /// Return the collection of UID corresponding to the hash if the hash has
0058    /// already been seen or nullptr otherwise.
0059    const RUidColl *Find(const HashValue &hash) const;
0060 
0061    /// If the hash is there, return false. Otherwise, insert the hash and UID
0062    /// collection and return true.
0063    bool Insert(const HashValue &hash, RUidColl &&coll) const;
0064 
0065    /// Return the hash object corresponding to the buffer.
0066    static HashValue Hash(char *buf, int len);
0067 };
0068 
0069 inline bool operator==(const RConcurrentHashColl::HashValue &lhs, const RConcurrentHashColl::HashValue &rhs)
0070 {
0071    auto l = lhs.Get();
0072    auto r = rhs.Get();
0073    return l[0] == r[0] && l[1] == r[1] && l[2] == r[2] && l[3] == r[3];
0074 }
0075 
0076 } // End NS Internal
0077 } // End NS ROOT
0078 
0079 namespace std {
0080 template <>
0081 struct less<ROOT::Internal::RConcurrentHashColl::HashValue> {
0082    bool operator()(const ROOT::Internal::RConcurrentHashColl::HashValue &lhs, const ROOT::Internal::RConcurrentHashColl::HashValue &rhs) const
0083    {
0084       /// Check piece by piece the 4 64 bits ints which make up the hash.
0085       auto l = lhs.Get();
0086       auto r = rhs.Get();
0087       // clang-format off
0088       return l[0] < r[0] ? true :
0089                l[0] > r[0] ? false :
0090                  l[1] < r[1] ? true :
0091                    l[1] > r[1] ? false :
0092                      l[2] < r[2] ? true :
0093                        l[2] > r[2] ? false :
0094                          l[3] < r[3] ? true : false;
0095       // clang-format on
0096    }
0097 };
0098 } // End NS std
0099 
0100 #endif