File indexing completed on 2023-03-17 10:39:10
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
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
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
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
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 }