Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-26 11:32:33

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 <functional>
0017 #include "Rtypes.h"
0018 
0019 namespace ROOT {
0020 
0021 class TRWSpinLock;
0022 
0023 namespace Internal {
0024 
0025 struct RHashMap;
0026 using RUidColl = std::vector<Int_t>;
0027 
0028 /// This class is a thread-safe associative collection connecting
0029 /// a 256 bits digest/hash to a collection of uid (integer)
0030 /// This is used in the handling of the StreamerInfo record in TFile.
0031 class RConcurrentHashColl {
0032 private:
0033    mutable std::unique_ptr<RHashMap> fHashMap;
0034    mutable std::unique_ptr<ROOT::TRWSpinLock> fRWLock;
0035 
0036 public:
0037    class HashValue {
0038       friend std::ostream &operator<<(std::ostream &os, const RConcurrentHashColl::HashValue &h);
0039 
0040    private:
0041       ULong64_t fDigest[4] = {0, 0, 0, 0};
0042 
0043    public:
0044       HashValue() = default;
0045       HashValue(const char *data, int len);
0046       ULong64_t const *Get() const { return fDigest; }
0047 
0048       /// Return the 64-bit hash of this 256-bit long digest/hash (4 x 64-bit)
0049       size_t ShortHash() const noexcept
0050       {
0051          std::hash<ULong64_t> hasher;
0052          return hasher(fDigest[0]) ^ hasher(fDigest[1]) ^ hasher(fDigest[2]) ^ hasher(fDigest[3]);
0053       }
0054    };
0055 
0056    RConcurrentHashColl();
0057    ~RConcurrentHashColl();
0058 
0059    /// Return the collection of UID corresponding to the hash if the hash has
0060    /// already been seen or nullptr otherwise.
0061    const RUidColl *Find(const HashValue &hash) const;
0062 
0063    /// If the hash is there, return false. Otherwise, insert the hash and UID
0064    /// collection and return true.
0065    bool Insert(const HashValue &hash, RUidColl &&coll) const;
0066 
0067    /// Return the hash object corresponding to the buffer.
0068    static HashValue Hash(char *buf, int len);
0069 };
0070 
0071 inline bool operator==(const RConcurrentHashColl::HashValue &lhs, const RConcurrentHashColl::HashValue &rhs)
0072 {
0073    auto l = lhs.Get();
0074    auto r = rhs.Get();
0075    return l[0] == r[0] && l[1] == r[1] && l[2] == r[2] && l[3] == r[3];
0076 }
0077 
0078 } // namespace Internal
0079 } // namespace ROOT
0080 
0081 namespace std {
0082 template <>
0083 struct less<ROOT::Internal::RConcurrentHashColl::HashValue> {
0084    bool operator()(const ROOT::Internal::RConcurrentHashColl::HashValue &lhs,
0085                    const ROOT::Internal::RConcurrentHashColl::HashValue &rhs) const
0086    {
0087       /// Check piece by piece the 4 64 bits ints which make up the hash.
0088       auto l = lhs.Get();
0089       auto r = rhs.Get();
0090       // clang-format off
0091       return l[0] < r[0] ? true :
0092                l[0] > r[0] ? false :
0093                  l[1] < r[1] ? true :
0094                    l[1] > r[1] ? false :
0095                      l[2] < r[2] ? true :
0096                        l[2] > r[2] ? false :
0097                          l[3] < r[3] ? true : false;
0098       // clang-format on
0099    }
0100 };
0101 } // namespace std
0102 
0103 #endif