File indexing completed on 2023-03-17 10:39:10
0001 #include <algorithm>
0002 #include <cassert>
0003 #include <utility>
0004
0005 #include "Alignment/Geners/interface/CPP11_auto_ptr.hh"
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
0080
0081
0082
0083
0084
0085
0086
0087
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 CPP11_auto_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 CPP11_auto_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 }