Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:44:55

0001 #include "Alignment/Geners/interface/GeneralCatalog.hh"
0002 #include "Alignment/Geners/interface/IOException.hh"
0003 #include "Alignment/Geners/interface/binaryIO.hh"
0004 
0005 #include <algorithm>
0006 #include <cassert>
0007 #include <memory>
0008 #include <utility>
0009 
0010 namespace gs {
0011   GeneralCatalog::GeneralCatalog() : smallestId_(1ULL), largestId_(0) {}
0012 
0013   void GeneralCatalog::findByName(const NameMap &m,
0014                                   const SearchSpecifier &namePattern,
0015                                   std::vector<unsigned long long> *found) const {
0016     typedef NameMap::const_iterator Nameiter;
0017 
0018     if (namePattern.useRegex()) {
0019       const Nameiter itend = m.end();
0020       for (Nameiter it = m.begin(); it != itend; ++it)
0021         if (namePattern.matches(it->first))
0022           found->push_back(it->second->id());
0023     } else {
0024       const std::pair<Nameiter, Nameiter> limits = m.equal_range(namePattern.pattern());
0025       for (Nameiter it = limits.first; it != limits.second; ++it)
0026         found->push_back(it->second->id());
0027     }
0028   }
0029 
0030   bool GeneralCatalog::addEntry(const SPtr inptr) {
0031     assert(inptr.get());
0032 
0033     const bool first = records_.empty();
0034     const unsigned long long id = inptr->id();
0035     if (id && records_.insert(std::make_pair(id, inptr)).second) {
0036       recordMap_[inptr->category()].insert(std::make_pair(inptr->name(), inptr));
0037       if (first) {
0038         smallestId_ = id;
0039         largestId_ = id;
0040       } else {
0041         if (id < smallestId_)
0042           smallestId_ = id;
0043         if (id > largestId_)
0044           largestId_ = id;
0045       }
0046       return true;
0047     } else
0048       return false;
0049   }
0050 
0051   bool GeneralCatalog::removeEntry(const unsigned long long id) {
0052     typedef RecordMap::iterator Mapiter;
0053     typedef NameMap::iterator Nameiter;
0054 
0055     IdMap::iterator rit = records_.find(id);
0056     if (rit == records_.end())
0057       return false;
0058 
0059     const SPtr item = rit->second;
0060     records_.erase(rit);
0061 
0062     bool found = false;
0063     const Mapiter mit = recordMap_.find(item->category());
0064     assert(mit != recordMap_.end());
0065     const std::pair<Nameiter, Nameiter> limits = mit->second.equal_range(item->name());
0066     for (Nameiter nit = limits.first; nit != limits.second; ++nit)
0067       if (nit->second->id() == id) {
0068         mit->second.erase(nit);
0069         found = true;
0070         break;
0071       }
0072     assert(found);
0073     if (mit->second.empty())
0074       recordMap_.erase(mit);
0075 
0076     if (records_.empty()) {
0077       recordMap_.clear();
0078       smallestId_ = 0;
0079       largestId_ = 0;
0080     } else if (id == smallestId_ || id == largestId_) {
0081       IdMap::const_iterator it = records_.begin();
0082       smallestId_ = it->first;
0083       largestId_ = it->first;
0084       const IdMap::const_iterator itend = records_.end();
0085       for (++it; it != itend; ++it)
0086         if (it->first < smallestId_)
0087           smallestId_ = it->first;
0088         else if (it->first > largestId_)
0089           largestId_ = it->first;
0090     }
0091     return true;
0092   }
0093 
0094   unsigned long long GeneralCatalog::makeEntry(const ItemDescriptor &descriptor,
0095                                                const unsigned compressionCode,
0096                                                const unsigned long long itemLength,
0097                                                const ItemLocation &loc,
0098                                                const unsigned long long offset) {
0099     const unsigned long long nextId = records_.empty() ? 1ULL : largestId_ + 1;
0100     lastEntry_ = SPtr(new CatalogEntry(descriptor, nextId, compressionCode, itemLength, loc, offset));
0101     assert(addEntry(lastEntry_));
0102     return nextId;
0103   }
0104 
0105   void GeneralCatalog::search(const SearchSpecifier &namePattern,
0106                               const SearchSpecifier &categoryPattern,
0107                               std::vector<unsigned long long> *found) const {
0108     typedef RecordMap::const_iterator Mapiter;
0109 
0110     assert(found);
0111     found->clear();
0112 
0113     const Mapiter endMap = recordMap_.end();
0114     if (categoryPattern.useRegex()) {
0115       for (Mapiter it = recordMap_.begin(); it != endMap; ++it)
0116         if (categoryPattern.matches(it->first))
0117           findByName(it->second, namePattern, found);
0118     } else {
0119       Mapiter it = recordMap_.find(categoryPattern.pattern());
0120       if (it != endMap)
0121         findByName(it->second, namePattern, found);
0122     }
0123     std::sort(found->begin(), found->end());
0124   }
0125 
0126   bool GeneralCatalog::isEqual(const AbsCatalog &other) const {
0127     if ((void *)this == (void *)(&other))
0128       return true;
0129     const GeneralCatalog &r = static_cast<const GeneralCatalog &>(other);
0130     if (smallestId_ != r.smallestId_)
0131       return false;
0132     if (largestId_ != r.largestId_)
0133       return false;
0134     if (records_.size() != r.records_.size())
0135       return false;
0136     IdMap::const_iterator itend = records_.end();
0137     IdMap::const_iterator itend2 = r.records_.end();
0138     for (IdMap::const_iterator it = records_.begin(); it != itend; ++it) {
0139       IdMap::const_iterator it2 = r.records_.find(it->first);
0140       if (it2 == itend2)
0141         return false;
0142       if (!(*it->second == *it2->second))
0143         return false;
0144     }
0145     return true;
0146   }
0147 
0148   // Version 1 write function
0149   // bool GeneralCatalog::write(std::ostream& os) const
0150   // {
0151   //     if (!ClassId::makeId<CatalogEntry>().write(os))
0152   //         return false;
0153   //     if (!ClassId::makeId<ItemLocation>().write(os))
0154   //         return false;
0155 
0156   //     // Sort item ids in the increasing order first
0157   //     std::vector<unsigned long long> idlist;
0158   //     const unsigned long sz = records_.size();
0159   //     idlist.reserve(sz);
0160   //     const IdMap::const_iterator itend = records_.end();
0161   //     for (IdMap::const_iterator it = records_.begin(); it != itend; ++it)
0162   //         idlist.push_back(it->first);
0163   //     std::sort(idlist.begin(), idlist.end());
0164 
0165   //     // Now, write the catalog records in the order of increasing ids
0166   //     for (unsigned long i=0; i<sz; ++i)
0167   //     {
0168   //         IdMap::const_iterator it = records_.find(idlist[i]);
0169   //         if (!it->second->write(os))
0170   //             return false;
0171   //     }
0172 
0173   //     return true;
0174   // }
0175 
0176   bool GeneralCatalog::write(std::ostream &os) const {
0177     const unsigned long sz = records_.size();
0178     long long ltmp = sz;
0179     write_pod(os, ltmp);
0180     if (os.fail())
0181       return false;
0182     if (!ClassId::makeId<CatalogEntry>().write(os))
0183       return false;
0184     if (!ClassId::makeId<ItemLocation>().write(os))
0185       return false;
0186 
0187     // Sort item ids in the increasing order first
0188     std::vector<unsigned long long> idlist;
0189     idlist.reserve(sz);
0190     const IdMap::const_iterator itend = records_.end();
0191     for (IdMap::const_iterator it = records_.begin(); it != itend; ++it)
0192       idlist.push_back(it->first);
0193     std::sort(idlist.begin(), idlist.end());
0194 
0195     // Now, write the catalog records in the order of increasing ids
0196     for (unsigned long i = 0; i < sz; ++i) {
0197       IdMap::const_iterator it = records_.find(idlist[i]);
0198       if (!it->second->write(os))
0199         return false;
0200     }
0201 
0202     return true;
0203   }
0204 
0205   GeneralCatalog *GeneralCatalog::read(const ClassId &id, std::istream &in) {
0206     static const ClassId current(ClassId::makeId<GeneralCatalog>());
0207     id.ensureSameName(current);
0208     id.ensureVersionInRange(1, version());
0209 
0210     if (id.version() == 1)
0211       return read_v1(in);
0212 
0213     long long nRecords;
0214     read_pod(in, &nRecords);
0215     if (nRecords < 0)
0216       return read_v1(in);
0217 
0218     ClassId rId(in, 1);
0219     ClassId locId(in, 1);
0220 
0221     GeneralCatalog *catalog = new GeneralCatalog();
0222     bool ok = true;
0223     for (long long recnum = 0; ok && recnum < nRecords; ++recnum) {
0224       CatalogEntry *rec = CatalogEntry::read(rId, locId, in);
0225       if (rec) {
0226         if (!catalog->addEntry(std::shared_ptr<const CatalogEntry>(rec)))
0227           ok = false;
0228       } else
0229         ok = false;
0230     }
0231 
0232     if (!ok) {
0233       delete catalog;
0234       throw IOInvalidData(
0235           "In gs::GeneralCatalog::read: "
0236           "duplicate item id. "
0237           "Catalog is corrupted.");
0238     }
0239     return catalog;
0240   }
0241 
0242   GeneralCatalog *GeneralCatalog::read_v1(std::istream &in) {
0243     ClassId rId(in, 1);
0244     ClassId locId(in, 1);
0245 
0246     GeneralCatalog *catalog = new GeneralCatalog();
0247     bool ok = true;
0248     for (in.peek(); ok && !in.eof(); in.peek()) {
0249       CatalogEntry *rec = CatalogEntry::read(rId, locId, in);
0250       if (rec) {
0251         if (!catalog->addEntry(std::shared_ptr<const CatalogEntry>(rec)))
0252           ok = false;
0253       } else
0254         ok = false;
0255     }
0256 
0257     if (!ok) {
0258       delete catalog;
0259       throw IOInvalidData(
0260           "In gs::GeneralCatalog::read_v1: "
0261           "duplicate item id. "
0262           "Catalog is corrupted.");
0263     }
0264     return catalog;
0265   }
0266 
0267   std::shared_ptr<const CatalogEntry> GeneralCatalog::retrieveEntry(const unsigned long long id) const {
0268     IdMap::const_iterator it = records_.find(id);
0269     if (it == records_.end()) {
0270       CatalogEntry *ptr = nullptr;
0271       return std::shared_ptr<const CatalogEntry>(ptr);
0272     } else
0273       return it->second;
0274   }
0275 
0276   bool GeneralCatalog::retrieveStreampos(unsigned long long id,
0277                                          unsigned *compressionCode,
0278                                          unsigned long long *length,
0279                                          std::streampos *pos) const {
0280     IdMap::const_iterator it = records_.find(id);
0281     if (it == records_.end())
0282       return false;
0283 
0284     assert(compressionCode);
0285     assert(length);
0286     assert(pos);
0287 
0288     *compressionCode = it->second->compressionCode();
0289     *length = it->second->itemLength();
0290     *pos = it->second->location().streamPosition();
0291 
0292     return true;
0293   }
0294 }  // namespace gs