Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 08:49:58

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    private:
0040       ULong64_t fDigest[4] = {0, 0, 0, 0};
0041 
0042    public:
0043       HashValue() = default;
0044       HashValue(const char *data, int len);
0045       ULong64_t const *Get() const { return fDigest; }
0046 
0047       /// Return the hash value for this object
0048       size_t Hash() const noexcept {
0049          std::hash<ULong64_t> hasher;
0050          return hasher(fDigest[0]) ^ hasher(fDigest[1])
0051                ^ hasher(fDigest[2]) ^ hasher(fDigest[3]);
0052       }
0053    };
0054 
0055    RConcurrentHashColl();
0056    ~RConcurrentHashColl();
0057 
0058    /// Return the collection of UID corresponding to the hash if the hash has
0059    /// already been seen or nullptr otherwise.
0060    const RUidColl *Find(const HashValue &hash) const;
0061 
0062    /// If the hash is there, return false. Otherwise, insert the hash and UID
0063    /// collection and return true.
0064    bool Insert(const HashValue &hash, RUidColl &&coll) const;
0065 
0066    /// Return the hash object corresponding to the buffer.
0067    static HashValue Hash(char *buf, int len);
0068 };
0069 
0070 inline bool operator==(const RConcurrentHashColl::HashValue &lhs, const RConcurrentHashColl::HashValue &rhs)
0071 {
0072    auto l = lhs.Get();
0073    auto r = rhs.Get();
0074    return l[0] == r[0] && l[1] == r[1] && l[2] == r[2] && l[3] == r[3];
0075 }
0076 
0077 } // End NS Internal
0078 } // End NS ROOT
0079 
0080 namespace std {
0081 template <>
0082 struct less<ROOT::Internal::RConcurrentHashColl::HashValue> {
0083    bool operator()(const ROOT::Internal::RConcurrentHashColl::HashValue &lhs, const ROOT::Internal::RConcurrentHashColl::HashValue &rhs) const
0084    {
0085       /// Check piece by piece the 4 64 bits ints which make up the hash.
0086       auto l = lhs.Get();
0087       auto r = rhs.Get();
0088       // clang-format off
0089       return l[0] < r[0] ? true :
0090                l[0] > r[0] ? false :
0091                  l[1] < r[1] ? true :
0092                    l[1] > r[1] ? false :
0093                      l[2] < r[2] ? true :
0094                        l[2] > r[2] ? false :
0095                          l[3] < r[3] ? true : false;
0096       // clang-format on
0097    }
0098 };
0099 } // End NS std
0100 
0101 #endif