Skip to content

Commit 38b1eaf

Browse files
committed
Use internal reference counting in CaloCellGeometry
This removes the need for std::shared_ptr in PFRecHit and should reduce memory usage.
1 parent 6a9a979 commit 38b1eaf

File tree

14 files changed

+240
-73
lines changed

14 files changed

+240
-73
lines changed

DataFormats/ParticleFlowReco/interface/PFRecHit.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "DataFormats/Common/interface/RefToBase.h"
1818

1919
#include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
20+
#include "Geometry/CaloGeometry/interface/CaloCellGeometryMayOwnPtr.h"
2021

2122
namespace reco {
2223

@@ -50,11 +51,8 @@ namespace reco {
5051
/// default constructor. Sets energy and position to zero
5152
PFRecHit() {}
5253

53-
PFRecHit(std::shared_ptr<const CaloCellGeometry> caloCell,
54-
unsigned int detId,
55-
PFLayer::Layer layer,
56-
float energy,
57-
uint32_t flags = 0)
54+
PFRecHit(
55+
CaloCellGeometryMayOwnPtr caloCell, unsigned int detId, PFLayer::Layer layer, float energy, uint32_t flags = 0)
5856
: caloCell_(std::move(caloCell)), detId_(detId), layer_(layer), energy_(energy), flags_(flags) {}
5957

6058
/// copy
@@ -139,7 +137,7 @@ namespace reco {
139137
Neighbours buildNeighbours(unsigned int n) const { return Neighbours(neighbours_.data(), n); }
140138

141139
/// cell geometry
142-
std::shared_ptr<const CaloCellGeometry> caloCell_ = nullptr;
140+
CaloCellGeometryMayOwnPtr caloCell_;
143141

144142
///cell detid
145143
unsigned int detId_ = 0;

Geometry/CaloGeometry/interface/CaloCellGeometry.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <array>
1313
#include <string>
1414
#include <cassert>
15+
#include <atomic>
1516

1617
/** \class CaloCellGeometry
1718
@@ -61,6 +62,8 @@ class CaloCellGeometry {
6162
typedef std::vector<ParVec> ParVecVec;
6263
typedef EZMgrFL<CCGFloat> ParMgr;
6364

65+
friend class CaloCellGeometryMayOwnPtr;
66+
6467
static constexpr unsigned int k_cornerSize = 8;
6568

6669
using RepCorners = std::array<RhoEtaPhi, k_cornerSize>;
@@ -114,8 +117,12 @@ class CaloCellGeometry {
114117

115118
CaloCellGeometry(const CornersVec& cv, const CCGFloat* par);
116119

117-
CaloCellGeometry(void);
120+
CaloCellGeometry();
118121

122+
CaloCellGeometry(CaloCellGeometry&&) = default;
123+
CaloCellGeometry(CaloCellGeometry const&) = default;
124+
CaloCellGeometry& operator=(CaloCellGeometry&&) = default;
125+
CaloCellGeometry& operator=(CaloCellGeometry const&) = default;
119126
// MUST be called by children constructors
120127
void initSpan() {
121128
initCorners(m_corners);
@@ -146,6 +153,10 @@ class CaloCellGeometry {
146153
m_repCorners[i] = {getCorners()[i].perp(), getCorners()[i].eta(), getCorners()[i].barePhi()};
147154
}
148155

156+
//These methods are ONLY used by CaloCellGeometryMayOwnPtr
157+
void increment() const { ++m_ref.m_count; }
158+
bool decrement() const { return 0 == --m_ref.m_count; }
159+
149160
GlobalPoint m_refPoint;
150161
GlobalPoint m_backPoint;
151162
CornersVec m_corners;
@@ -154,6 +165,15 @@ class CaloCellGeometry {
154165
float m_dEta;
155166
float m_dPhi;
156167
std::array<RhoEtaPhi, k_cornerSize> m_repCorners;
168+
struct RefCount {
169+
RefCount() = default;
170+
RefCount(RefCount&&) {}
171+
RefCount(RefCount const&) {}
172+
RefCount& operator=(RefCount&&) { return *this; }
173+
RefCount& operator=(const RefCount&) { return *this; }
174+
175+
mutable std::atomic<unsigned int> m_count = 0;
176+
} m_ref;
157177
};
158178

159179
std::ostream& operator<<(std::ostream& s, const CaloCellGeometry& cell);

Geometry/CaloGeometry/interface/CaloCellGeometryMayOwnPtr.h

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,31 +29,50 @@
2929

3030
class CaloCellGeometryMayOwnPtr {
3131
public:
32-
explicit CaloCellGeometryMayOwnPtr(CaloCellGeometry const* iPtr, bool iOwn) noexcept : ptr_{iPtr}, own_{iOwn} {}
3332
explicit CaloCellGeometryMayOwnPtr(std::unique_ptr<CaloCellGeometry const> iPtr) noexcept
34-
: ptr_{iPtr.release()}, own_{true} {}
33+
: ptr_{iPtr.release()}, own_{ptr_ != nullptr} {
34+
if (own_) {
35+
ptr_->increment();
36+
}
37+
}
3538
explicit CaloCellGeometryMayOwnPtr(CaloCellGeometryPtr const& iPtr) noexcept : ptr_{iPtr.get()}, own_{false} {}
3639

3740
~CaloCellGeometryMayOwnPtr() noexcept {
38-
if (own_) {
41+
if (own_ and ptr_->decrement()) {
3942
delete ptr_;
4043
}
4144
}
4245
CaloCellGeometryMayOwnPtr() noexcept = default;
43-
CaloCellGeometryMayOwnPtr(const CaloCellGeometryMayOwnPtr&) noexcept = delete;
46+
CaloCellGeometryMayOwnPtr(const CaloCellGeometryMayOwnPtr& iPtr) noexcept : ptr_{iPtr.ptr_}, own_{iPtr.own_} {
47+
if (own_) {
48+
ptr_->increment();
49+
}
50+
}
4451
CaloCellGeometryMayOwnPtr(CaloCellGeometryMayOwnPtr&& iPtr) noexcept : ptr_{iPtr.ptr_}, own_{iPtr.own_} {
4552
iPtr.ptr_ = nullptr;
4653
iPtr.own_ = false;
4754
}
48-
CaloCellGeometryMayOwnPtr& operator=(CaloCellGeometryMayOwnPtr const&) noexcept = delete;
49-
CaloCellGeometryMayOwnPtr& operator=(CaloCellGeometryMayOwnPtr&& iPtr) noexcept {
55+
CaloCellGeometryMayOwnPtr& operator=(CaloCellGeometryMayOwnPtr const& iPtr) noexcept {
56+
//Even if someone does `foo = foo` this will work
57+
auto tmpPtr = iPtr.ptr_;
58+
auto tmpOwn = iPtr.own_;
59+
CaloCellGeometryMayOwnPtr temp(std::move(*this));
60+
ptr_ = tmpPtr;
61+
own_ = tmpOwn;
5062
if (own_) {
51-
delete ptr_;
63+
ptr_->increment();
64+
}
65+
return *this;
66+
}
67+
CaloCellGeometryMayOwnPtr& operator=(CaloCellGeometryMayOwnPtr&& iPtr) noexcept {
68+
if (&iPtr != this) {
69+
CaloCellGeometryMayOwnPtr temp(std::move(*this));
70+
71+
ptr_ = iPtr.ptr_;
72+
own_ = iPtr.own_;
73+
iPtr.ptr_ = nullptr;
74+
iPtr.own_ = false;
5275
}
53-
ptr_ = iPtr.ptr_;
54-
own_ = iPtr.own_;
55-
iPtr.ptr_ = nullptr;
56-
iPtr.own_ = false;
5776
return *this;
5877
}
5978

@@ -63,17 +82,6 @@ class CaloCellGeometryMayOwnPtr {
6382

6483
operator CaloCellGeometry const*() const { return ptr_; }
6584

66-
//transfers ownership to a shared_ptr
67-
std::shared_ptr<CaloCellGeometry const> releaseToShared() {
68-
auto p = ptr_;
69-
ptr_ = nullptr;
70-
if (own_) {
71-
own_ = false;
72-
return std::shared_ptr<CaloCellGeometry const>(p);
73-
}
74-
return std::shared_ptr<CaloCellGeometry const>(p, no_delete());
75-
}
76-
7785
private:
7886
struct no_delete {
7987
void operator()(const void*) {}

Geometry/CaloGeometry/interface/IdealZPrism.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,8 @@ class IdealZPrism final : public CaloCellGeometry {
5757

5858
void vocalCorners(Pt3DVec& vec, const CCGFloat* pv, Pt3D& ref) const override;
5959

60-
// corrected geom for PF
61-
std::shared_ptr<const IdealZPrism> forPF() const {
62-
static const auto do_not_delete = [](const void*) {};
63-
auto cell = std::shared_ptr<const IdealZPrism>(m_geoForPF.get(), do_not_delete);
64-
return cell;
65-
}
60+
// corrected geom for PF. memory is owned by this object and not transfered to caller.
61+
const IdealZPrism* forPF() const { return m_geoForPF.get(); }
6662

6763
private:
6864
void initCorners(CornersVec&) override;

0 commit comments

Comments
 (0)