Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:56:21

0001 #include <algorithm>
0002 #include <cassert>
0003 #include <utility>
0004 
0005 #include <memory>
0006 #include "Alignment/Geners/interface/ContiguousCatalog.hh"
0007 #include "Alignment/Geners/interface/IOException.hh"
0008 #include "Alignment/Geners/interface/binaryIO.hh"
0009 
0010 namespace gs {
0011   void ContiguousCatalog::findByName(const NameMap &m,
0012                                      const SearchSpecifier &namePattern,
0013                                      std::vector<unsigned long long> *found) const {
0014     typedef NameMap::const_iterator Nameiter;
0015 
0016     if (namePattern.useRegex()) {
0017       const Nameiter itend = m.end();
0018       for (Nameiter it = m.begin(); it != itend; ++it)
0019         if (namePattern.matches(it->first))
0020           found->push_back(it->second);
0021     } else {
0022       const std::pair<Nameiter, Nameiter> limits = m.equal_range(namePattern.pattern());
0023       for (Nameiter it = limits.first; it != limits.second; ++it)
0024         found->push_back(it->second);
0025     }
0026   }
0027 
0028   unsigned long long ContiguousCatalog::makeEntry(const ItemDescriptor &descriptor,
0029                                                   const unsigned compressionCode,
0030                                                   const unsigned long long itemLength,
0031                                                   const ItemLocation &loc,
0032                                                   const unsigned long long offset) {
0033     const unsigned long long nextId = records_.size() + firstId_;
0034     lastEntry_ = SPtr(new CatalogEntry(descriptor, nextId, compressionCode, itemLength, loc, offset));
0035     records_.push_back(lastEntry_);
0036     recordMap_[descriptor.category()].insert(std::make_pair(descriptor.name(), nextId));
0037 
0038     return nextId;
0039   }
0040 
0041   void ContiguousCatalog::search(const SearchSpecifier &namePattern,
0042                                  const SearchSpecifier &categoryPattern,
0043                                  std::vector<unsigned long long> *found) const {
0044     typedef RecordMap::const_iterator Mapiter;
0045 
0046     assert(found);
0047     found->clear();
0048 
0049     const Mapiter endMap = recordMap_.end();
0050     if (categoryPattern.useRegex()) {
0051       for (Mapiter it = recordMap_.begin(); it != endMap; ++it)
0052         if (categoryPattern.matches(it->first))
0053           findByName(it->second, namePattern, found);
0054     } else {
0055       Mapiter it = recordMap_.find(categoryPattern.pattern());
0056       if (it != endMap)
0057         findByName(it->second, namePattern, found);
0058     }
0059     std::sort(found->begin(), found->end());
0060   }
0061 
0062   bool ContiguousCatalog::isEqual(const AbsCatalog &other) const {
0063     if ((void *)this == (void *)(&other))
0064       return true;
0065     const ContiguousCatalog &r = static_cast<const ContiguousCatalog &>(other);
0066     if (firstId_ != r.firstId_)
0067       return false;
0068     if (recordMap_ != r.recordMap_)
0069       return false;
0070     const unsigned long nRecords = records_.size();
0071     if (nRecords != r.records_.size())
0072       return false;
0073     for (unsigned long i = 0; i < nRecords; ++i)
0074       if (*records_[i] != *r.records_[i])
0075         return false;
0076     return true;
0077   }
0078 
0079   // Version 1 write function
0080   // bool ContiguousCatalog::write(std::ostream& os) const
0081   // {
0082   //     bool status = ClassId::makeId<CatalogEntry>().write(os) &&
0083   //                   ClassId::makeId<ItemLocation>().write(os);
0084   //     const unsigned long long sz = records_.size();
0085   //     for (unsigned long long i=0; i<sz && status; ++i)
0086   //         status = records_[i]->write(os);
0087   //     return status;
0088   // }
0089 
0090   bool ContiguousCatalog::write(std::ostream &os) const {
0091     const unsigned long long sz = records_.size();
0092     long long nRecords = sz;
0093     write_pod(os, nRecords);
0094     bool status = !os.fail() && ClassId::makeId<CatalogEntry>().write(os) && ClassId::makeId<ItemLocation>().write(os);
0095     for (unsigned long long i = 0; i < sz && status; ++i)
0096       status = records_[i]->write(os);
0097     return status;
0098   }
0099 
0100   ContiguousCatalog *ContiguousCatalog::read(const ClassId &cid, std::istream &in) {
0101     static const ClassId current(ClassId::makeId<ContiguousCatalog>());
0102     cid.ensureSameName(current);
0103     cid.ensureVersionInRange(1, version());
0104 
0105     if (cid.version() == 1)
0106       return read_v1(in);
0107 
0108     long long nRecords;
0109     read_pod(in, &nRecords);
0110     if (nRecords < 0)
0111       return read_v1(in);
0112 
0113     ClassId rId(in, 1);
0114     ClassId locId(in, 1);
0115 
0116     std::unique_ptr<ContiguousCatalog> catalog(new ContiguousCatalog());
0117     bool firstEntry = true;
0118     for (long long recnum = 0; recnum < nRecords; ++recnum) {
0119       CatalogEntry *rec = CatalogEntry::read(rId, locId, in);
0120       if (rec) {
0121         const unsigned long long id = rec->id();
0122         if (firstEntry) {
0123           catalog->firstId_ = id;
0124           firstEntry = false;
0125         } else {
0126           const unsigned long long nextId = catalog->records_.size() + catalog->firstId_;
0127           if (id != nextId) {
0128             delete rec;
0129             throw IOInvalidData(
0130                 "In gs::ContiguousCatalog::read:"
0131                 " unexpected item id. "
0132                 "Catalog is corrupted.");
0133           }
0134         }
0135         catalog->records_.push_back(SPtr(rec));
0136         catalog->recordMap_[rec->category()].insert(std::make_pair(rec->name(), id));
0137       } else
0138         throw IOInvalidData(
0139             "In gs::ContiguousCatalog::read:"
0140             " failed to read catalog entry");
0141     }
0142     return catalog.release();
0143   }
0144 
0145   ContiguousCatalog *ContiguousCatalog::read_v1(std::istream &in) {
0146     ClassId rId(in, 1);
0147     ClassId locId(in, 1);
0148 
0149     std::unique_ptr<ContiguousCatalog> catalog(new ContiguousCatalog());
0150     bool firstEntry = true;
0151     for (in.peek(); !in.eof(); in.peek()) {
0152       CatalogEntry *rec = CatalogEntry::read(rId, locId, in);
0153       if (rec) {
0154         const unsigned long long id = rec->id();
0155         if (firstEntry) {
0156           catalog->firstId_ = id;
0157           firstEntry = false;
0158         } else {
0159           const unsigned long long nextId = catalog->records_.size() + catalog->firstId_;
0160           if (id != nextId) {
0161             delete rec;
0162             throw IOInvalidData(
0163                 "In gs::ContiguousCatalog::read_v1:"
0164                 " unexpected item id. "
0165                 "Catalog is corrupted.");
0166           }
0167         }
0168         catalog->records_.push_back(SPtr(rec));
0169         catalog->recordMap_[rec->category()].insert(std::make_pair(rec->name(), id));
0170       } else
0171         throw IOInvalidData(
0172             "In gs::ContiguousCatalog::read_v1:"
0173             " failed to read catalog entry");
0174     }
0175     return catalog.release();
0176   }
0177 
0178   std::shared_ptr<const CatalogEntry> ContiguousCatalog::retrieveEntry(const unsigned long long id) const {
0179     if (id >= firstId_ && id < records_.size() + firstId_)
0180       return records_[id - firstId_];
0181     else {
0182       CatalogEntry *ptr = nullptr;
0183       return std::shared_ptr<const CatalogEntry>(ptr);
0184     }
0185   }
0186 
0187   bool ContiguousCatalog::retrieveStreampos(unsigned long long id,
0188                                             unsigned *compressionCode,
0189                                             unsigned long long *length,
0190                                             std::streampos *pos) const {
0191     assert(compressionCode);
0192     assert(length);
0193     assert(pos);
0194 
0195     if (id >= firstId_ && id < records_.size() + firstId_) {
0196       const std::shared_ptr<const CatalogEntry> &rec(records_[id - firstId_]);
0197       *compressionCode = rec->compressionCode();
0198       *length = rec->itemLength();
0199       *pos = rec->location().streamPosition();
0200       return true;
0201     } else
0202       return false;
0203   }
0204 }  // namespace gs