CMS 3D CMS Logo

GeneralCatalog.cc
Go to the documentation of this file.
1 #include "Alignment/Geners/interface/GeneralCatalog.hh"
2 #include "Alignment/Geners/interface/IOException.hh"
3 #include "Alignment/Geners/interface/binaryIO.hh"
4 
5 #include <algorithm>
6 #include <cassert>
7 #include <memory>
8 #include <utility>
9 
10 namespace gs {
11  GeneralCatalog::GeneralCatalog() : smallestId_(1ULL), largestId_(0) {}
12 
13  void GeneralCatalog::findByName(const NameMap &m,
14  const SearchSpecifier &namePattern,
15  std::vector<unsigned long long> *found) const {
16  typedef NameMap::const_iterator Nameiter;
17 
18  if (namePattern.useRegex()) {
19  const Nameiter itend = m.end();
20  for (Nameiter it = m.begin(); it != itend; ++it)
21  if (namePattern.matches(it->first))
22  found->push_back(it->second->id());
23  } else {
24  const std::pair<Nameiter, Nameiter> limits = m.equal_range(namePattern.pattern());
25  for (Nameiter it = limits.first; it != limits.second; ++it)
26  found->push_back(it->second->id());
27  }
28  }
29 
30  bool GeneralCatalog::addEntry(const SPtr inptr) {
31  assert(inptr.get());
32 
33  const bool first = records_.empty();
34  const unsigned long long id = inptr->id();
35  if (id && records_.insert(std::make_pair(id, inptr)).second) {
36  recordMap_[inptr->category()].insert(std::make_pair(inptr->name(), inptr));
37  if (first) {
38  smallestId_ = id;
39  largestId_ = id;
40  } else {
41  if (id < smallestId_)
42  smallestId_ = id;
43  if (id > largestId_)
44  largestId_ = id;
45  }
46  return true;
47  } else
48  return false;
49  }
50 
51  bool GeneralCatalog::removeEntry(const unsigned long long id) {
52  typedef RecordMap::iterator Mapiter;
53  typedef NameMap::iterator Nameiter;
54 
55  IdMap::iterator rit = records_.find(id);
56  if (rit == records_.end())
57  return false;
58 
59  const SPtr item = rit->second;
60  records_.erase(rit);
61 
62  bool found = false;
63  const Mapiter mit = recordMap_.find(item->category());
64  assert(mit != recordMap_.end());
65  const std::pair<Nameiter, Nameiter> limits = mit->second.equal_range(item->name());
66  for (Nameiter nit = limits.first; nit != limits.second; ++nit)
67  if (nit->second->id() == id) {
68  mit->second.erase(nit);
69  found = true;
70  break;
71  }
72  assert(found);
73  if (mit->second.empty())
74  recordMap_.erase(mit);
75 
76  if (records_.empty()) {
77  recordMap_.clear();
78  smallestId_ = 0;
79  largestId_ = 0;
80  } else if (id == smallestId_ || id == largestId_) {
81  IdMap::const_iterator it = records_.begin();
82  smallestId_ = it->first;
83  largestId_ = it->first;
84  const IdMap::const_iterator itend = records_.end();
85  for (++it; it != itend; ++it)
86  if (it->first < smallestId_)
87  smallestId_ = it->first;
88  else if (it->first > largestId_)
89  largestId_ = it->first;
90  }
91  return true;
92  }
93 
94  unsigned long long GeneralCatalog::makeEntry(const ItemDescriptor &descriptor,
95  const unsigned compressionCode,
96  const unsigned long long itemLength,
97  const ItemLocation &loc,
98  const unsigned long long offset) {
99  const unsigned long long nextId = records_.empty() ? 1ULL : largestId_ + 1;
100  lastEntry_ = SPtr(new CatalogEntry(descriptor, nextId, compressionCode, itemLength, loc, offset));
101  assert(addEntry(lastEntry_));
102  return nextId;
103  }
104 
105  void GeneralCatalog::search(const SearchSpecifier &namePattern,
106  const SearchSpecifier &categoryPattern,
107  std::vector<unsigned long long> *found) const {
108  typedef RecordMap::const_iterator Mapiter;
109 
110  assert(found);
111  found->clear();
112 
113  const Mapiter endMap = recordMap_.end();
114  if (categoryPattern.useRegex()) {
115  for (Mapiter it = recordMap_.begin(); it != endMap; ++it)
116  if (categoryPattern.matches(it->first))
117  findByName(it->second, namePattern, found);
118  } else {
119  Mapiter it = recordMap_.find(categoryPattern.pattern());
120  if (it != endMap)
121  findByName(it->second, namePattern, found);
122  }
123  std::sort(found->begin(), found->end());
124  }
125 
126  bool GeneralCatalog::isEqual(const AbsCatalog &other) const {
127  if ((void *)this == (void *)(&other))
128  return true;
129  const GeneralCatalog &r = static_cast<const GeneralCatalog &>(other);
130  if (smallestId_ != r.smallestId_)
131  return false;
132  if (largestId_ != r.largestId_)
133  return false;
134  if (records_.size() != r.records_.size())
135  return false;
136  IdMap::const_iterator itend = records_.end();
137  IdMap::const_iterator itend2 = r.records_.end();
138  for (IdMap::const_iterator it = records_.begin(); it != itend; ++it) {
139  IdMap::const_iterator it2 = r.records_.find(it->first);
140  if (it2 == itend2)
141  return false;
142  if (!(*it->second == *it2->second))
143  return false;
144  }
145  return true;
146  }
147 
148  // Version 1 write function
149  // bool GeneralCatalog::write(std::ostream& os) const
150  // {
151  // if (!ClassId::makeId<CatalogEntry>().write(os))
152  // return false;
153  // if (!ClassId::makeId<ItemLocation>().write(os))
154  // return false;
155 
156  // // Sort item ids in the increasing order first
157  // std::vector<unsigned long long> idlist;
158  // const unsigned long sz = records_.size();
159  // idlist.reserve(sz);
160  // const IdMap::const_iterator itend = records_.end();
161  // for (IdMap::const_iterator it = records_.begin(); it != itend; ++it)
162  // idlist.push_back(it->first);
163  // std::sort(idlist.begin(), idlist.end());
164 
165  // // Now, write the catalog records in the order of increasing ids
166  // for (unsigned long i=0; i<sz; ++i)
167  // {
168  // IdMap::const_iterator it = records_.find(idlist[i]);
169  // if (!it->second->write(os))
170  // return false;
171  // }
172 
173  // return true;
174  // }
175 
176  bool GeneralCatalog::write(std::ostream &os) const {
177  const unsigned long sz = records_.size();
178  long long ltmp = sz;
179  write_pod(os, ltmp);
180  if (os.fail())
181  return false;
182  if (!ClassId::makeId<CatalogEntry>().write(os))
183  return false;
184  if (!ClassId::makeId<ItemLocation>().write(os))
185  return false;
186 
187  // Sort item ids in the increasing order first
188  std::vector<unsigned long long> idlist;
189  idlist.reserve(sz);
190  const IdMap::const_iterator itend = records_.end();
191  for (IdMap::const_iterator it = records_.begin(); it != itend; ++it)
192  idlist.push_back(it->first);
193  std::sort(idlist.begin(), idlist.end());
194 
195  // Now, write the catalog records in the order of increasing ids
196  for (unsigned long i = 0; i < sz; ++i) {
197  IdMap::const_iterator it = records_.find(idlist[i]);
198  if (!it->second->write(os))
199  return false;
200  }
201 
202  return true;
203  }
204 
205  GeneralCatalog *GeneralCatalog::read(const ClassId &id, std::istream &in) {
206  static const ClassId current(ClassId::makeId<GeneralCatalog>());
207  id.ensureSameName(current);
208  id.ensureVersionInRange(1, version());
209 
210  if (id.version() == 1)
211  return read_v1(in);
212 
213  long long nRecords;
214  read_pod(in, &nRecords);
215  if (nRecords < 0)
216  return read_v1(in);
217 
218  ClassId rId(in, 1);
219  ClassId locId(in, 1);
220 
221  GeneralCatalog *catalog = new GeneralCatalog();
222  bool ok = true;
223  for (long long recnum = 0; ok && recnum < nRecords; ++recnum) {
224  CatalogEntry *rec = CatalogEntry::read(rId, locId, in);
225  if (rec) {
226  if (!catalog->addEntry(std::shared_ptr<const CatalogEntry>(rec)))
227  ok = false;
228  } else
229  ok = false;
230  }
231 
232  if (!ok) {
233  delete catalog;
234  throw IOInvalidData(
235  "In gs::GeneralCatalog::read: "
236  "duplicate item id. "
237  "Catalog is corrupted.");
238  }
239  return catalog;
240  }
241 
242  GeneralCatalog *GeneralCatalog::read_v1(std::istream &in) {
243  ClassId rId(in, 1);
244  ClassId locId(in, 1);
245 
246  GeneralCatalog *catalog = new GeneralCatalog();
247  bool ok = true;
248  for (in.peek(); ok && !in.eof(); in.peek()) {
249  CatalogEntry *rec = CatalogEntry::read(rId, locId, in);
250  if (rec) {
251  if (!catalog->addEntry(std::shared_ptr<const CatalogEntry>(rec)))
252  ok = false;
253  } else
254  ok = false;
255  }
256 
257  if (!ok) {
258  delete catalog;
259  throw IOInvalidData(
260  "In gs::GeneralCatalog::read_v1: "
261  "duplicate item id. "
262  "Catalog is corrupted.");
263  }
264  return catalog;
265  }
266 
267  std::shared_ptr<const CatalogEntry> GeneralCatalog::retrieveEntry(const unsigned long long id) const {
268  IdMap::const_iterator it = records_.find(id);
269  if (it == records_.end()) {
270  CatalogEntry *ptr = nullptr;
271  return std::shared_ptr<const CatalogEntry>(ptr);
272  } else
273  return it->second;
274  }
275 
276  bool GeneralCatalog::retrieveStreampos(unsigned long long id,
277  unsigned *compressionCode,
278  unsigned long long *length,
279  std::streampos *pos) const {
280  IdMap::const_iterator it = records_.find(id);
281  if (it == records_.end())
282  return false;
283 
284  assert(compressionCode);
285  assert(length);
286  assert(pos);
287 
288  *compressionCode = it->second->compressionCode();
289  *length = it->second->itemLength();
290  *pos = it->second->location().streamPosition();
291 
292  return true;
293  }
294 } // namespace gs
std::vector< T >::const_iterator search(const cond::Time_t &val, const std::vector< T > &container)
Definition: IOVProxy.cc:21
assert(be >=bs)
Definition: AbsArchive.cc:46