OpenMS
UniqueIdIndexer.h
Go to the documentation of this file.
1 // Copyright (c) 2002-2023, The OpenMS Team -- EKU Tuebingen, ETH Zurich, and FU Berlin
2 // SPDX-License-Identifier: BSD-3-Clause
3 //
4 // --------------------------------------------------------------------------
5 // $Maintainer: Chris Bielow $
6 // $Authors: Clemens Groepl $
7 // --------------------------------------------------------------------------
8 
9 #pragma once
10 
13 
14 #ifdef _MSC_VER // disable some BOOST warnings that distract from ours
15 # pragma warning( push ) // save warning state
16 # pragma warning( disable : 4396 )
17 #endif
18 
19 #include <unordered_map>
20 #include <sstream>
21 
22 #ifdef _MSC_VER
23 # pragma warning( pop ) // restore old warning state
24 #endif
25 
26 
27 namespace OpenMS
28 {
29 
39  template<typename T>
41  {
42 public:
43  typedef std::unordered_map<UInt64, Size> UniqueIdMap;
44 
60  Size
61  uniqueIdToIndex(UInt64 unique_id) const
62  {
63  Size index;
64  try
65  {
66  index = uniqueid_to_index_.at(unique_id);
67  if (getBase_().at(index).getUniqueId() != unique_id)
68  {
69  throw std::out_of_range("unique_id_to_index_");
70  }
71  }
72  catch (std::out_of_range &)
73  {
74  try
75  {
76  this->updateUniqueIdToIndex();
77  index = uniqueid_to_index_.at(unique_id);
78  }
79  catch (std::out_of_range &)
80  {
81  index = -1; // which means: invalid
82  }
83  }
84  return index;
85  }
86 
91  void
93  {
94  Size num_valid_unique_id = 0;
95  // add or update unique id of existing features
96  for (Size index = 0; index < getBase_().size(); ++index)
97  {
98  UInt64 unique_id = getBase_()[index].getUniqueId();
99  if (UniqueIdInterface::isValid(unique_id))
100  {
101  uniqueid_to_index_[unique_id] = index;
102  ++num_valid_unique_id;
103  }
104  }
105  // remove invalid or outdated entries
107  for (UniqueIdMap::iterator iter = uniqueid_to_index_.begin(); iter != uniqueid_to_index_.end(); /* see loop */)
108  {
109  if (iter->second >= getBase_().size() || getBase_()[iter->second].getUniqueId() != iter->first)
110  {
111  iter = uniqueid_to_index_.erase(iter);
112  }
113  else
114  {
115  ++iter;
116  }
117  }
118  if (uniqueid_to_index_.size() != num_valid_unique_id)
119  {
120  std::stringstream ss;
121  ss << "Duplicate valid unique ids detected! RandomAccessContainer has size()==" << getBase_().size();
122  ss << ", num_valid_unique_id==" << num_valid_unique_id;
123  ss << ", uniqueid_to_index_.size()==" << uniqueid_to_index_.size();
124  throw Exception::Postcondition(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, ss.str());
125  }
126  return;
127  }
128 
142  Size
144  {
145  Size invalid_uids(0);
146  uniqueid_to_index_.clear();
147  // add unique id of existing features
148  for (Size index = 0; index < getBase_().size(); ++index)
149  {
150  UInt64 unique_id = getBase_()[index].getUniqueId();
151  if (!UniqueIdInterface::isValid(unique_id))
152  {
153  getBase_()[index].ensureUniqueId();
154  unique_id = getBase_()[index].getUniqueId();
155  }
156 
157  // see if UID already present
158  while (uniqueid_to_index_.find(unique_id) != uniqueid_to_index_.end()) // double entry!
159  {
160  getBase_()[index].setUniqueId();
161  unique_id = getBase_()[index].getUniqueId();
162  ++invalid_uids;
163  }
164 
165  uniqueid_to_index_[unique_id] = index;
166 
167  }
168 
169  return invalid_uids;
170  }
171 
176  void
178  {
179  std::swap(uniqueid_to_index_, rhs.uniqueid_to_index_);
180  return;
181  }
182 
183 protected:
184 
187  const auto& getBase_() const
188  {
189  const T& derived = static_cast<const T&>(*this); // using CRTP
190  return derived.getData();
191  }
192 
195  auto& getBase_()
196  {
197  T& derived = static_cast<T&>(*this); // using CRTP
198  return derived.getData();
199  }
200 
206 
207  };
208 
209 } //namespace OpenMS
210 
Postcondition failed exception.
Definition: Exception.h:147
A base class for containers with elements derived from UniqueIdInterface. This adds functionality to ...
Definition: UniqueIdIndexer.h:41
const auto & getBase_() const
A little helper to get access to the base (!) class RandomAccessContainer.
Definition: UniqueIdIndexer.h:187
std::unordered_map< UInt64, Size > UniqueIdMap
Definition: UniqueIdIndexer.h:43
UniqueIdMap uniqueid_to_index_
hash map from unique id to index of features
Definition: UniqueIdIndexer.h:205
Size uniqueIdToIndex(UInt64 unique_id) const
Returns the index of the feature with the given unique id, or Size(-1) if none exists in this random ...
Definition: UniqueIdIndexer.h:61
Size resolveUniqueIdConflicts()
Assign new UID's to doubly occurring UID's.
Definition: UniqueIdIndexer.h:143
void updateUniqueIdToIndex() const
Updates the hash map from unique id to index.
Definition: UniqueIdIndexer.h:92
auto & getBase_()
A little helper to get access to the base (!) class RandomAccessContainer.
Definition: UniqueIdIndexer.h:195
void swap(UniqueIdIndexer &rhs)
Swap.
Definition: UniqueIdIndexer.h:177
static bool isValid(UInt64 unique_id)
Returns true if the unique_id is valid, false otherwise.
Definition: UniqueIdInterface.h:42
@ INVALID
Definition: UniqueIdInterface.h:34
OPENMS_UINT64_TYPE UInt64
Unsigned integer type (64bit)
Definition: Types.h:51
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:101
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:22