ATLAS Offline Software
TileMutableDataContainer.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
3 */
4 /*
5  */
6 /**
7  * @file TileEvent/TileMutableDataContainer.icc
8  * @author scott snyder <snyder@bnl.gov>
9  * @date Oct, 2018
10  * @brief Helper for holding non-const raw data prior to recording in SG.
11  */
12 
13 
14 /**
15  * @brief Constructor.
16  * @param createColl If true, create all collections now.
17  * @param type Hash type (from TileFragHash::TYPE).
18  * @param unit Measurement units for amplitude data.
19  * @param ownPolicy Ownership mode for collections.
20  *
21  * Call status() after this to check for errors.
22  */
23 template <class BASE>
24 TileMutableDataContainer<BASE>::TileMutableDataContainer
25  (bool createColl /*= false*/,
26  TYPE type /*= TileFragHash::Default*/,
27  UNIT unit /*= TileRawChannelUnit::ADCcounts*/,
28  SG::OwnershipPolicy ownPolicy /*= SG::OWN_ELEMENTS*/)
29  : BASE (false, type, unit, ownPolicy),
30  m_locked (false),
31  m_sc (StatusCode::SUCCESS),
32  m_defaultType (type),
33  m_defaultUnit (unit)
34 {
35  if (createColl) {
36  // Create all collections.
37  const TileFragHash& hashFunc = this->hashFunc();
38  int ncoll = hashFunc.max();
39  for (int i=0; i<ncoll;++i) {
40  TileFragHash::ID frag = hashFunc.identifier(i);
41  auto coll = std::make_unique<Collection> (frag, ownPolicy) ;
42  if (addCollection (std::move (coll),
43  static_cast<IdentifierHash>(i)).isFailure())
44  {
45  m_sc = StatusCode::FAILURE;
46  }
47  }
48  }
49 }
50 
51 
52 /**
53  * @brief Copy constructor.
54  * @param other Container to copy.
55  *
56  * This is a deep copy; all contained collections and channels will be copied.
57  * Call status() after this to check for errors.
58  */
59 template <class BASE>
60 TileMutableDataContainer<BASE>::TileMutableDataContainer
61  (const BASE& other)
62  : BASE (false,
63  other.get_type(),
64  other.get_unit(),
65  SG::OWN_ELEMENTS),
66  m_locked (false),
67  m_sc (StatusCode::SUCCESS),
68  m_defaultType (other.get_type()),
69  m_defaultUnit (other.get_unit())
70 {
71  this->set_bsflags (other.get_bsflags());
72  for (IdentifierHash hash : other.GetAllCurrentHashes()) {
73  const Collection* coll = other.indexFindPtr (hash);
74  auto newColl = std::make_unique<Collection> (*coll);
75  if (addCollection (std::move (newColl), hash).isFailure()) {
76  m_sc = StatusCode::FAILURE;
77  }
78  }
79 }
80 
81 
82 /**
83  * @brief Add a collection to the container.
84  * @param coll Collection ot add.
85  * @param hash Hash value for the collection.
86  *
87  * We maintain a non-const reference to the collection.
88  */
89 template <class BASE>
90 StatusCode
91 TileMutableDataContainer<BASE>::addCollection (std::unique_ptr<Collection> coll,
92  IdentifierHash hash)
93 {
94  if (hash >= m_mutableCollections.size()) {
95  m_mutableCollections.resize (hash+1);
96  }
97  m_mutableCollections[hash] = coll.get();
98  return BASE::addOrDelete (std::move (coll), hash);
99 }
100 
101 
102 /**
103  * @brief Add a new channel.
104  * @param rch Channel to add.
105  *
106  * This should be used for owning container (created with SG::OWN_ELEMENTS).
107  * A new collection will be created if needed.
108  * In that case, we maintain a non-const reference to it.
109  */
110 template <class BASE>
111 StatusCode
112 TileMutableDataContainer<BASE>::push_back (std::unique_ptr<Element> rch)
113 {
114  int frag = rch->frag_ID();
115  IdentifierHash hash = static_cast<IdentifierHash>(this->hashFunc()(frag));
116 
117  // Find the collection; create a new one if needed.
118  Collection* coll = indexFindPtr (hash);
119  if (!coll) {
120  auto newColl = std::make_unique<Collection> (frag, SG::OWN_ELEMENTS);
121  coll = newColl.get();
122  if (addCollection (std::move (newColl), hash).isFailure()) {
123  return StatusCode::FAILURE;
124  }
125  }
126 
127  coll->push_back (std::move (rch));
128  return StatusCode::SUCCESS;
129 }
130 
131 
132 /**
133  * @brief Add a new channel.
134  * @param rch Channel to add.
135  *
136  * This should be used for non-owning container (created with SG::VIEW_ELEMENTS).
137  * A new collection will be created if needed.
138  * In that case, we maintain a non-const reference to it.
139  */
140 template <class BASE>
141 StatusCode
142 TileMutableDataContainer<BASE>::push_back (Element* rch)
143 {
144  int frag = rch->frag_ID();
145  IdentifierHash hash = static_cast<IdentifierHash>(this->hashFunc()(frag));
146 
147  // Find the collection; create a new one if needed.
148  Collection* coll = indexFindPtr (hash);
149  if (!coll) {
150  auto newColl = std::make_unique<Collection> (frag, SG::OWN_ELEMENTS);
151  coll = newColl.get();
152  if (addCollection (std::move (newColl), hash).isFailure()) {
153  return StatusCode::FAILURE;
154  }
155  }
156 
157  coll->push_back (rch);
158  return StatusCode::SUCCESS;
159 }
160 
161 
162 /**
163  * @brief Look up a (non-const) collection via hash.
164  * @param hash Hash value to find.
165  */
166 template <class BASE>
167 typename TileMutableDataContainer<BASE>::Collection*
168 TileMutableDataContainer<BASE>::indexFindPtr (IdentifierHash hash)
169 {
170  if (!m_locked && hash < m_mutableCollections.size()) {
171  return m_mutableCollections[hash];
172  }
173  return nullptr;
174 }
175 
176 
177 /**
178  * @brief Return the error status from the constructors.
179  */
180 template <class BASE>
181 StatusCode TileMutableDataContainer<BASE>::status() const
182 {
183  return m_sc;
184 }
185 
186 
187 /**
188  * @brief Lock this object.
189  *
190  * Called when this object is locked in SG.
191  * Prohibit non-const acces to this container.
192  */
193 template <class BASE>
194 void TileMutableDataContainer<BASE>::lock()
195 {
196  m_locked = true;
197 }
198 
199 
200 /**
201  * @brief Recycle this object for use in another event.
202  *
203  * This is called from AthenaKernel/RecyclableDataObject when this object
204  * is released by StoreGate. Unlock the object so that non-const access
205  * is again possible, and clear out the contents if the collections.
206  */
207 template <class BASE>
208 void TileMutableDataContainer<BASE>::recycle()
209 {
210  // ??? Try to verify that this object is not in SG? Check refcount??
211  m_locked = false;
212  for (IdentifierHash hash : this->GetAllCurrentHashes()) {
213  Collection* coll = this->indexFindPtr (hash);
214  coll->clear();
215  }
216 
217  this->set_type (m_defaultType);
218  this->set_unit (m_defaultUnit);
219  this->set_bsflags (0);
220 }