File indexing completed on 2025-06-17 01:30:09
0001 #include "catch.hpp"
0002
0003 #include "DataFormats/Common/interface/DetSetNew.h"
0004 #include "DataFormats/Common/interface/DetSetVectorNew.h"
0005 #include "DataFormats/Common/interface/DetSetAlgorithm.h"
0006 #include "DataFormats/Common/interface/DetSet2RangeMap.h"
0007
0008 #include "FWCore/Utilities/interface/EDMException.h"
0009
0010 #include <algorithm>
0011 #include <vector>
0012
0013 namespace {
0014 struct B {
0015 virtual ~B() {}
0016 virtual B *clone() const = 0;
0017 };
0018
0019 struct T : public B {
0020 T(float iv = 0) : v(iv) {}
0021 float v;
0022 bool operator==(T t) const { return v == t.v; }
0023
0024 T *clone() const final { return new T(*this); }
0025 };
0026
0027 bool operator==(T const &t, B const &b) {
0028 T const *p = dynamic_cast<T const *>(&b);
0029 return p && p->v == t.v;
0030 }
0031
0032 bool operator==(B const &b, T const &t) { return t == b; }
0033 }
0034 typedef edmNew::DetSetVector<T> DSTV;
0035 typedef edmNew::DetSet<T> DST;
0036 typedef edmNew::det_id_type det_id_type;
0037 typedef DSTV::FastFiller FF;
0038 typedef DSTV::TSFastFiller TSFF;
0039
0040 class TestDetSet {
0041 public:
0042 static auto &data(DSTV &detsets) { return detsets.m_data; }
0043 static auto &item(FF &ff) { return ff.m_item; }
0044 static auto &item(TSFF &ff) { return ff.m_item; }
0045 };
0046 namespace {
0047 struct VerifyIter {
0048 VerifyIter(std::vector<DSTV::data_type> *sv, unsigned int in = 1, int iincr = 1) : n(in), incr(iincr), sv_(sv) {}
0049
0050 void operator()(DST const &df) {
0051 if (df.id() > 1000) {
0052 REQUIRE(df.size() == 0);
0053 return;
0054 }
0055 REQUIRE(df.id() == 20 + n);
0056 REQUIRE(df.size() == n);
0057 std::vector<DST::data_type> v1(n);
0058 std::vector<DST::data_type> v2(n);
0059 std::copy(df.begin(), df.end(), v2.begin());
0060 std::copy(sv_->begin(), sv_->begin() + n, v1.begin());
0061 REQUIRE(v1 == v2);
0062 n += incr;
0063 }
0064
0065 unsigned int n;
0066 int incr;
0067 std::vector<DSTV::data_type> *sv_;
0068 };
0069
0070 struct cmp10 {
0071 bool operator()(DSTV::id_type i1, DSTV::id_type i2) const { return i1 / 10 < i2 / 10; }
0072 };
0073
0074 std::pair<unsigned int, cmp10> acc(unsigned int i) { return std::make_pair(i * 10, cmp10()); }
0075
0076 struct VerifyAlgos {
0077 VerifyAlgos(std::vector<DSTV::data_type const *> &iv) : n(0), v(iv) {}
0078
0079 void operator()(DSTV::data_type const &d) {
0080 REQUIRE(d == *v[n]);
0081 REQUIRE(&d == v[n]);
0082 ++n;
0083 }
0084
0085 int n;
0086 std::vector<DSTV::data_type const *> const &v;
0087 };
0088
0089 struct Getter final : public DSTV::Getter {
0090 Getter(std::vector<DSTV::data_type> *sv) : ntot(0), sv_(*sv) {}
0091
0092 void fill(TSFF &ff) const override {
0093 aborted = false;
0094 try {
0095 const int n = ff.id() - 20;
0096 REQUIRE(n > 0);
0097 ff.resize(n);
0098 int nCopied = n;
0099 if (static_cast<size_t>(n) > sv_.size()) {
0100 nCopied = sv_.size();
0101 }
0102 std::copy(sv_.begin(), sv_.begin() + nCopied, ff.begin());
0103 if (ff.full()) {
0104 ff.abort();
0105 aborted = true;
0106 } else {
0107 ntot += n;
0108 }
0109 } catch (edmNew::CapacityExaustedException const &) {
0110 REQUIRE(false);
0111 }
0112 }
0113
0114 mutable unsigned int ntot;
0115 mutable bool aborted = false;
0116 std::vector<DSTV::data_type> &sv_;
0117 };
0118 }
0119
0120 TEST_CASE("DetSetNew", "[DetSetNew]") {
0121 std::vector<DSTV::data_type> sv(10);
0122 DSTV::data_type v[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
0123 std::copy(v, v + 10, sv.begin());
0124
0125 SECTION("constructor") {
0126 DSTV detsets(2);
0127 REQUIRE(!detsets.onDemand());
0128 REQUIRE(detsets.subdetId() == 2);
0129 REQUIRE(detsets.size() == 0);
0130 REQUIRE(detsets.empty());
0131 REQUIRE(detsets.dataSize() == 0);
0132 detsets.resize(3, 10);
0133 REQUIRE(detsets.size() == 3);
0134 REQUIRE(detsets.dataSize() == 10);
0135 REQUIRE(!detsets.empty());
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 SECTION("swap") {
0149 DSTV detsets2(3);
0150 detsets.swap(detsets2);
0151 REQUIRE(detsets.subdetId() == 3);
0152 REQUIRE(detsets.size() == 0);
0153 REQUIRE(detsets.dataSize() == 0);
0154 REQUIRE(detsets2.subdetId() == 2);
0155 REQUIRE(detsets2.size() == 3);
0156 REQUIRE(detsets2.dataSize() == 10);
0157 REQUIRE(!detsets2.onDemand());
0158 }
0159 SECTION("move") {
0160 DSTV detsets3(4);
0161 detsets = std::move(detsets3);
0162 REQUIRE(detsets.subdetId() == 4);
0163 REQUIRE(detsets.size() == 0);
0164 REQUIRE(detsets.dataSize() == 0);
0165 DSTV detsets5(std::move(detsets));
0166 REQUIRE(detsets5.subdetId() == 4);
0167 REQUIRE(detsets5.size() == 0);
0168 REQUIRE(detsets5.dataSize() == 0);
0169 SECTION("copy") {
0170 DSTV detsets4(detsets5);
0171 REQUIRE(detsets4.subdetId() == 4);
0172 REQUIRE(detsets4.size() == 0);
0173 REQUIRE(detsets4.dataSize() == 0);
0174 }
0175 }
0176 }
0177
0178 SECTION("inserting") {
0179 DSTV detsets(2);
0180 unsigned int ntot = 0;
0181 for (unsigned int n = 1; n < 5; ++n) {
0182 ntot += n;
0183 unsigned int id = 20 + n;
0184 DST df = detsets.insert(id, n);
0185 REQUIRE(detsets.size() == n);
0186 REQUIRE(detsets.dataSize() == ntot);
0187 REQUIRE(detsets.detsetSize(n - 1) == n);
0188 REQUIRE(df.size() == n);
0189 REQUIRE(df.id() == id);
0190
0191 std::copy(sv.begin(), sv.begin() + n, df.begin());
0192
0193 DSTV detsets2(detsets);
0194 REQUIRE(detsets2.size() == n);
0195 REQUIRE(detsets2.dataSize() == ntot);
0196 REQUIRE(detsets2.detsetSize(n - 1) == n);
0197
0198 std::vector<DST::data_type> v1(n);
0199 std::vector<DST::data_type> v2(n);
0200 std::vector<DST::data_type> v3(n);
0201 std::copy(TestDetSet::data(detsets).begin() + ntot - n, TestDetSet::data(detsets).begin() + ntot, v2.begin());
0202 std::copy(TestDetSet::data(detsets2).begin() + ntot - n, TestDetSet::data(detsets2).begin() + ntot, v3.begin());
0203 std::copy(sv.begin(), sv.begin() + n, v1.begin());
0204 REQUIRE(v1 == v2);
0205 REQUIRE(v1 == v3);
0206 }
0207
0208
0209 REQUIRE_THROWS_MATCHES(
0210 detsets.insert(22, 6), edm::Exception, Catch::Predicate<edm::Exception>([](edm::Exception const &e) {
0211 return e.categoryCode() == edm::errors::InvalidReference;
0212 }));
0213 }
0214
0215 SECTION("filling") {
0216 DSTV detsets(2);
0217 unsigned int ntot = 0;
0218 for (unsigned int n = 1; n < 5; ++n) {
0219 unsigned int id = 20 + n;
0220 FF ff(detsets, id);
0221 REQUIRE(detsets.size() == n);
0222 REQUIRE(detsets.dataSize() == ntot);
0223 REQUIRE(detsets.detsetSize(n - 1) == 0);
0224 REQUIRE(TestDetSet::item(ff).offset == int(detsets.dataSize()));
0225 REQUIRE(TestDetSet::item(ff).size == 0);
0226 REQUIRE(TestDetSet::item(ff).id == id);
0227 ntot += 1;
0228 ff.push_back(3.14);
0229 REQUIRE(detsets.dataSize() == ntot);
0230 REQUIRE(detsets.detsetSize(n - 1) == 1);
0231 REQUIRE(TestDetSet::data(detsets).back().v == 3.14f);
0232 REQUIRE(TestDetSet::item(ff).offset == int(detsets.dataSize()) - 1);
0233 REQUIRE(TestDetSet::item(ff).size == 1);
0234 ntot += n - 1;
0235 ff.resize(n);
0236 REQUIRE(detsets.dataSize() == ntot);
0237 REQUIRE(detsets.detsetSize(n - 1) == n);
0238 REQUIRE(TestDetSet::item(ff).offset == int(detsets.dataSize() - n));
0239 REQUIRE(TestDetSet::item(ff).size == n);
0240
0241 std::copy(sv.begin(), sv.begin() + n, ff.begin());
0242
0243 std::vector<DST::data_type> v1(n);
0244 std::vector<DST::data_type> v2(n);
0245 std::copy(TestDetSet::data(detsets).begin() + ntot - n, TestDetSet::data(detsets).begin() + ntot, v2.begin());
0246 std::copy(sv.begin(), sv.begin() + n, v1.begin());
0247 REQUIRE(v1 == v2);
0248 }
0249
0250
0251 {
0252 FF ff1(detsets, 30);
0253 REQUIRE(detsets.size() == 5);
0254 REQUIRE(detsets.exists(30));
0255 REQUIRE(detsets.isValid(30));
0256 }
0257 REQUIRE(detsets.size() == 4);
0258 REQUIRE(!detsets.exists(30));
0259 {
0260 FF ff1(detsets, 30, true);
0261 REQUIRE(detsets.size() == 5);
0262 REQUIRE(detsets.exists(30));
0263 REQUIRE(detsets.isValid(30));
0264 }
0265 REQUIRE(detsets.size() == 5);
0266 REQUIRE(detsets.exists(30));
0267
0268 {
0269 DSTV detsets2(detsets);
0270 REQUIRE(detsets2.size() == 5);
0271 REQUIRE(detsets2.exists(30));
0272 }
0273
0274 {
0275 unsigned int cs = detsets.dataSize();
0276 FF ff1(detsets, 31);
0277 ff1.resize(4);
0278 REQUIRE(detsets.size() == 6);
0279 REQUIRE(detsets.dataSize() == cs + 4);
0280 REQUIRE(detsets.exists(31));
0281 REQUIRE(detsets.isValid(31));
0282 ff1.abort();
0283 REQUIRE(detsets.size() == 5);
0284 REQUIRE(detsets.dataSize() == cs);
0285 REQUIRE(!detsets.exists(31));
0286 }
0287 REQUIRE(detsets.size() == 5);
0288 REQUIRE(!detsets.exists(31));
0289 { FF ff1(detsets, 32, true); }
0290 REQUIRE(detsets.size() == 6);
0291
0292 DSTV detsets2(detsets);
0293 REQUIRE(detsets2.size() == 6);
0294
0295 detsets.clean();
0296 REQUIRE(detsets.size() == 4);
0297 REQUIRE(!detsets.exists(30));
0298 REQUIRE(!detsets.exists(32));
0299
0300 REQUIRE(detsets2.size() == 6);
0301 REQUIRE(detsets2.exists(30));
0302 REQUIRE(detsets2.exists(32));
0303 detsets2.clean();
0304 REQUIRE(detsets2.size() == 4);
0305 REQUIRE(!detsets2.exists(30));
0306 REQUIRE(!detsets2.exists(32));
0307
0308
0309 REQUIRE_THROWS_MATCHES(
0310 FF(detsets, 22), edm::Exception, Catch::Predicate<edm::Exception>([](edm::Exception const &e) {
0311 return e.categoryCode() == edm::errors::InvalidReference;
0312 }));
0313 REQUIRE_THROWS_MATCHES(
0314 [](DSTV &d) {
0315 FF ff1(d, 44);
0316 FF ff2(d, 45);
0317 }(detsets),
0318 edm::Exception,
0319 Catch::Predicate<edm::Exception>(
0320 [](edm::Exception const &e) { return e.categoryCode() == edm::errors::LogicError; }));
0321 }
0322
0323 SECTION("filling using TSFastFiller") {
0324 DSTV detsets(2);
0325 detsets.reserve(5, 100);
0326 unsigned int ntot = 0;
0327 for (unsigned int n = 1; n < 5; ++n) {
0328 unsigned int id = 20 + n;
0329 {
0330 TSFF ff(detsets, id);
0331 REQUIRE(detsets.size() == n);
0332 REQUIRE(detsets.dataSize() == ntot);
0333 REQUIRE(TestDetSet::item(ff).size == 0);
0334 REQUIRE(ff.id() == id);
0335 ntot += 1;
0336 ff.push_back(3.14);
0337 REQUIRE(detsets.dataSize() == ntot - 1);
0338 REQUIRE(TestDetSet::item(ff).size == 0);
0339 REQUIRE(ff.size() == 1);
0340 ntot += n - 1;
0341 ff.resize(n);
0342 REQUIRE(ff.size() == n);
0343 std::copy(sv.begin(), sv.begin() + n, ff.begin());
0344 }
0345 REQUIRE(detsets.size() == n);
0346 REQUIRE(detsets.dataSize() == ntot);
0347
0348 std::vector<DST::data_type> v1(n);
0349 std::vector<DST::data_type> v2(n);
0350 std::copy(TestDetSet::data(detsets).begin() + ntot - n, TestDetSet::data(detsets).begin() + ntot, v2.begin());
0351 std::copy(sv.begin(), sv.begin() + n, v1.begin());
0352 REQUIRE(v1 == v2);
0353 }
0354
0355
0356 {
0357 TSFF ff1(detsets, 30);
0358 REQUIRE(detsets.exists(30));
0359 }
0360 REQUIRE(detsets.size() == 5);
0361 REQUIRE(detsets.exists(30));
0362 detsets.clean();
0363 REQUIRE(detsets.size() == 4);
0364 REQUIRE(!detsets.exists(30));
0365 unsigned int cs = detsets.dataSize();
0366 SECTION("abort") {
0367 TSFF ff1(detsets, 31);
0368 ff1.resize(4);
0369 ff1.abort();
0370 REQUIRE(detsets.size() == 5);
0371 REQUIRE(detsets.dataSize() == cs);
0372 SECTION("clean") {
0373 REQUIRE(detsets.exists(31));
0374 detsets.clean();
0375 REQUIRE(detsets.size() == 4);
0376 REQUIRE(!detsets.exists(31));
0377 }
0378 }
0379 SECTION("error conditions") {
0380 REQUIRE_THROWS_MATCHES(
0381 TSFF(detsets, 22), edm::Exception, Catch::Predicate<edm::Exception>([](edm::Exception const &e) {
0382 return e.categoryCode() == edm::errors::InvalidReference;
0383 }));
0384 REQUIRE_THROWS_MATCHES(
0385 [](DSTV &d) {
0386 TSFF ff1(d, 44);
0387 TSFF ff2(d, 45);
0388 }(detsets),
0389 edm::Exception,
0390 Catch::Predicate<edm::Exception>(
0391 [](edm::Exception const &e) { return e.categoryCode() == edm::errors::LogicError; }));
0392 }
0393 }
0394
0395 SECTION("iterator") {
0396 DSTV detsets(2);
0397 for (unsigned int n = 1; n < 5; ++n) {
0398 unsigned int id = 20 + n;
0399 FF ff(detsets, id);
0400 ff.resize(n);
0401 std::copy(sv.begin(), sv.begin() + n, ff.begin());
0402 }
0403 REQUIRE(std::for_each(detsets.begin(true), detsets.end(true), VerifyIter(&sv)).n == 5);
0404 {
0405 FF ff(detsets, 31);
0406 ff.resize(2);
0407 std::copy(sv.begin(), sv.begin() + 2, ff.begin());
0408 }
0409 {
0410 FF ff(detsets, 11);
0411 ff.resize(2);
0412 std::copy(sv.begin(), sv.begin() + 2, ff.begin());
0413 }
0414 {
0415 FF ff(detsets, 34);
0416 ff.resize(4);
0417 std::copy(sv.begin(), sv.begin() + 4, ff.begin());
0418 }
0419 DSTV::Range r = detsets.equal_range(30, cmp10());
0420 REQUIRE(r.second - r.first == 2);
0421 r = detsets.equal_range(40, cmp10());
0422 REQUIRE(r.second - r.first == 0);
0423
0424 SECTION("find") {
0425 REQUIRE(detsets.exists(22));
0426 REQUIRE(!detsets.exists(44));
0427 DST df = *detsets.find(22);
0428 REQUIRE(df.id() == 22);
0429 REQUIRE(df.size() == 2);
0430 }
0431 SECTION("indexing") {
0432 DST df = detsets[22];
0433 REQUIRE(df.id() == 22);
0434 REQUIRE(df.size() == 2);
0435 }
0436
0437 SECTION("find not found") {
0438 DSTV::const_iterator p = detsets.find(44);
0439 REQUIRE(p == detsets.end());
0440 }
0441 SECTION("invalid index") {
0442 REQUIRE_THROWS_MATCHES(detsets[44], edm::Exception, Catch::Predicate<edm::Exception>([](edm::Exception const &e) {
0443 return e.categoryCode() == edm::errors::InvalidReference;
0444 }));
0445 }
0446 }
0447
0448 SECTION("algorithm") {
0449 DSTV detsets(2);
0450 for (unsigned int n = 1; n < 5; ++n) {
0451 unsigned int id = 20 + n;
0452 FF ff(detsets, id);
0453 ff.resize(n);
0454 std::copy(sv.begin(), sv.begin() + n, ff.begin());
0455 }
0456 {
0457 FF ff(detsets, 31);
0458 ff.resize(2);
0459 std::copy(sv.begin(), sv.begin() + 2, ff.begin());
0460 }
0461 {
0462 FF ff(detsets, 11);
0463 ff.resize(2);
0464 std::copy(sv.begin(), sv.begin() + 2, ff.begin());
0465 }
0466 {
0467 FF ff(detsets, 34);
0468 ff.resize(4);
0469 std::copy(sv.begin(), sv.begin() + 4, ff.begin());
0470 }
0471 DSTV::Range r = detsetRangeFromPair(detsets, acc(3));
0472 REQUIRE(r.second - r.first == 2);
0473 r = edmNew::detsetRangeFromPair(detsets, acc(4));
0474 REQUIRE(r.second - r.first == 0);
0475 std::vector<DSTV::data_type const *> v;
0476 edmNew::copyDetSetRange(detsets, v, acc(3));
0477 VerifyAlgos va(v);
0478 edmNew::foreachDetSetObject(detsets, acc(3), va);
0479 }
0480
0481 SECTION("onDemand") {
0482 auto pg = std::make_shared<Getter>(&sv);
0483 Getter &g = *pg;
0484 REQUIRE(!g.aborted);
0485 std::vector<unsigned int> v = {21, 23, 25, 27, 1020};
0486 DSTV detsets(pg, v, 2);
0487 REQUIRE(g.ntot == 0);
0488 REQUIRE(detsets.onDemand());
0489 REQUIRE(detsets.exists(21));
0490 REQUIRE(!detsets.exists(22));
0491 REQUIRE(!detsets.isValid(21));
0492 REQUIRE(!detsets.isValid(22));
0493 detsets.reserve(5, 100);
0494 DST df = *detsets.find(21, true);
0495 REQUIRE(df.id() == 21);
0496 REQUIRE(df.size() == 1);
0497 REQUIRE(detsets.isValid(21));
0498 REQUIRE(!detsets.isValid(23));
0499 REQUIRE(g.ntot == 1);
0500 REQUIRE(!g.aborted);
0501 {
0502 DST df = detsets[25];
0503 REQUIRE(df.id() == 25);
0504 REQUIRE(df.size() == 5);
0505 REQUIRE(g.ntot == 1 + 5);
0506 REQUIRE(!g.aborted);
0507 }
0508 {
0509 DST df = detsets[1020];
0510 REQUIRE(df.id() == 1020);
0511 REQUIRE(df.size() == 0);
0512 REQUIRE(g.ntot == 1 + 5);
0513 REQUIRE(g.aborted);
0514 }
0515
0516 int i = 0;
0517 for (auto di = detsets.begin(); di != detsets.end(); ++di) {
0518 ++i;
0519 auto ds = *di;
0520 auto id = ds.id();
0521 REQUIRE((id == 1020 || (id > 20 && id < 28 && id % 2 == 1)));
0522 if (1020 == id || 21 == id || 25 == id)
0523 REQUIRE(ds.isValid());
0524 else
0525 REQUIRE(!ds.isValid());
0526 }
0527 REQUIRE(5 == i);
0528 REQUIRE(g.ntot == 1 + 5);
0529 REQUIRE(std::for_each(detsets.begin(true), detsets.end(true), VerifyIter(&sv, 1, 2)).n == 9);
0530 REQUIRE(std::for_each(detsets.begin(true), detsets.end(true), VerifyIter(&sv, 1, 2)).n == 9);
0531 REQUIRE(g.ntot == 1 + 3 + 5 + 7);
0532 SECTION("find not found") {
0533 DSTV::const_iterator p = detsets.find(22);
0534 REQUIRE(p == detsets.end());
0535 }
0536
0537 SECTION("invalid index") {
0538 REQUIRE_THROWS_MATCHES(detsets[22], edm::Exception, Catch::Predicate<edm::Exception>([](edm::Exception const &e) {
0539 return e.categoryCode() == edm::errors::InvalidReference;
0540 }));
0541 }
0542 DSTV detsets2;
0543 detsets2.swap(detsets);
0544 REQUIRE(detsets2.onDemand());
0545 DSTV detsets3;
0546 detsets3 = std::move(detsets2);
0547 REQUIRE(detsets3.onDemand());
0548 DSTV detsets5(std::move(detsets3));
0549 REQUIRE(detsets5.onDemand());
0550 DSTV detsets4(detsets5);
0551 REQUIRE(detsets4.onDemand());
0552 }
0553
0554 SECTION("toRangeMap") {
0555 DSTV detsets(2);
0556 for (unsigned int n = 1; n < 5; ++n) {
0557 unsigned int id = 20 + n;
0558 FF ff(detsets, id);
0559 ff.resize(n);
0560 std::copy(sv.begin(), sv.begin() + n, ff.begin());
0561 }
0562 {
0563 FF ff(detsets, 31);
0564 ff.resize(2);
0565 std::copy(sv.begin(), sv.begin() + 2, ff.begin());
0566 }
0567 {
0568 FF ff(detsets, 11);
0569 ff.resize(2);
0570 std::copy(sv.begin(), sv.begin() + 2, ff.begin());
0571 }
0572 {
0573 FF ff(detsets, 34);
0574 ff.resize(4);
0575 std::copy(sv.begin(), sv.begin() + 4, ff.begin());
0576 }
0577 SECTION("edmNew::copy") {
0578 typedef edm::RangeMap<det_id_type, edm::OwnVector<B> > RM;
0579 edm::RangeMap<det_id_type, edm::OwnVector<B> > rm;
0580 edmNew::copy(detsets, rm);
0581 rm.post_insert();
0582 std::vector<det_id_type> ids = rm.ids();
0583 REQUIRE(ids.size() == detsets.size());
0584 REQUIRE(rm.size() == detsets.dataSize());
0585 for (int i = 0; i < int(ids.size()); i++) {
0586 RM::range r = rm.get(ids[i]);
0587 DST df = *detsets.find(ids[i]);
0588 REQUIRE(static_cast<unsigned long>(r.second - r.first) == df.size());
0589 REQUIRE(std::equal(r.first, r.second, df.begin()));
0590 }
0591 }
0592 }
0593 }