Belle II Software development
datastore.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#include <framework/dataobjects/EventMetaData.h>
9#include <framework/dataobjects/ProfileInfo.h>
10#include <framework/datastore/StoreArray.h>
11#include <framework/datastore/StoreObjPtr.h>
12#include <framework/datastore/RelationsObject.h>
13#include <framework/utilities/TestHelpers.h>
14
15#include <gtest/gtest.h>
16
17#include <algorithm>
18
19using namespace std;
20using namespace Belle2;
21
22namespace {
24 class DataStoreTest : public ::testing::Test {
25 protected:
27 void SetUp() override
28 {
29 StoreObjPtr<EventMetaData> evtPtr;
30 StoreArray<EventMetaData> evtData;
31 StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
32 StoreArray<EventMetaData> evtDataEmpty("Empty");
33 StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
34 StoreArray<ProfileInfo> profileInfo;
35
37 evtPtr.registerInDataStore();
38 evtData.registerInDataStore();
39 evtDataDifferentName.registerInDataStore();
40 evtDataEmpty.registerInDataStore();
41 evtDataDifferentDurability.registerInDataStore();
42 profileInfo.registerInDataStore();
44
45 evtPtr.create();
46 evtPtr->setEvent(42);
47
48
49 ProfileInfo profileInfoObject(128, 64, 60.0);
50 for (int i = 0; i < 10; ++i) {
51 //direct construction
52 EventMetaData* newobj = evtData.appendNew();
53 newobj->setEvent(10 + i);
54
55 //copy-construction
56 EventMetaData newObj2;
57 newObj2.setEvent(20 + i);
58 evtDataDifferentName.appendNew(newObj2);
59
60 //fancy constructors
61 newobj = evtDataDifferentDurability.appendNew(30 + i);
62 ASSERT_TRUE(newobj != nullptr);
63
64 //copy-construct ProfileInfo objects
65 profileInfo.appendNew(profileInfoObject);
66 }
67 }
68
70 void TearDown() override
71 {
73 }
74
76 static void verifyContents()
77 {
78 StoreObjPtr<EventMetaData> evtPtr;
79 EXPECT_TRUE(evtPtr.isValid());
80 EXPECT_EQ(evtPtr->getEvent(), (unsigned long)42);
81
82 StoreArray<EventMetaData> evtData;
83 StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
84 StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
85 StoreArray<ProfileInfo> profileInfo;
86 EXPECT_EQ(evtData.getEntries(), 10);
87 EXPECT_EQ(evtDataDifferentName.getEntries(), 10);
88 EXPECT_EQ(evtDataDifferentDurability.getEntries(), 10);
89 EXPECT_EQ(profileInfo.getEntries(), 10);
90 for (int i = 0; i < 10; ++i) {
91 EXPECT_EQ((int)evtData[i]->getEvent(), 10 + i);
92 EXPECT_EQ((int)evtDataDifferentName[i]->getEvent(), 20 + i);
93 EXPECT_EQ((int)evtDataDifferentDurability[i]->getEvent(), 30 + i);
94
95 EXPECT_EQ(profileInfo[i]->getVirtualMemory(), 128u);
96 EXPECT_FLOAT_EQ(profileInfo[i]->getTimeInSec(), 60.0);
97 }
98 }
99
100 };
101
102 TEST_F(DataStoreTest, EntryNames)
103 {
104 EXPECT_EQ("JustSomeStuff", DataStore::defaultObjectName("JustSomeStuff"));
105 EXPECT_EQ("JustSomeStuff", DataStore::defaultObjectName("Belle2::Foo::JustSomeStuff"));
106 EXPECT_EQ("JustSomeStuffs", DataStore::defaultArrayName("Belle2::Foo::JustSomeStuff"));
107
108 EXPECT_EQ("MyOwnName", DataStore::arrayName<TObject>("MyOwnName"));
109 EXPECT_EQ("MyOwnName", DataStore::arrayName(TObject::Class(), "MyOwnName"));
110 EXPECT_EQ("TObjects", DataStore::arrayName<TObject>(""));
111 EXPECT_EQ("TObjects", DataStore::arrayName(TObject::Class(), ""));
112
113 EXPECT_EQ("MyOwnName", DataStore::objectName<TObject>("MyOwnName"));
114 EXPECT_EQ("MyOwnName", DataStore::objectName(TObject::Class(), "MyOwnName"));
115
116 EXPECT_EQ("TObject", DataStore::objectName<TObject>(""));
117 EXPECT_EQ("TObject", DataStore::objectName(TObject::Class(), ""));
118
119 EXPECT_EQ("EventMetaDatas", DataStore::arrayName<EventMetaData>(""));
120 EXPECT_EQ("GF2Track", DataStore::defaultObjectName("genfit::Track"));
121
122 EXPECT_EQ("AToB", DataStore::relationName("A", "B"));
124 EXPECT_EQ("EventMetaDatasToProfileInfos", relname);
125 }
126
127 TEST_F(DataStoreTest, GetTClass)
128 {
129 EXPECT_EQ(Belle2::EventMetaData::Class(), DataStore::getTClassFromDefaultObjectName("Belle2::EventMetaData"));
130 EXPECT_EQ(Belle2::EventMetaData::Class(), DataStore::getTClassFromDefaultObjectName("EventMetaData"));
131
132 EXPECT_EQ(Belle2::EventMetaData::Class(), DataStore::getTClassFromDefaultArrayName("Belle2::EventMetaDatas"));
133 EXPECT_EQ(Belle2::EventMetaData::Class(), DataStore::getTClassFromDefaultArrayName("EventMetaDatas"));
134 }
135
136
138 TEST_F(DataStoreTest, AttachTest)
139 {
141 EXPECT_TRUE(evtPtr);
142
144 EXPECT_TRUE(evtData);
145 StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
146 EXPECT_TRUE(evtDataDifferentName);
147 StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
148 EXPECT_TRUE(evtDataDifferentDurability);
149 StoreArray<ProfileInfo> profileInfo;
150 EXPECT_TRUE(profileInfo);
151 }
152
154 TEST_F(DataStoreTest, TypeTest)
155 {
156 //attach with incompatible type
157 EXPECT_B2FATAL(StoreArray<ProfileInfo>("EventMetaDatas").isValid());
158 EXPECT_B2FATAL(StoreObjPtr<ProfileInfo>("EventMetaData").isValid());
159
160 //attaching objects to array and vice versa shouldn't work
161 //neither should the store allow objects with same name/durability
162 //as existing arrays
163 EXPECT_B2FATAL(StoreArray<EventMetaData>("EventMetaData").isValid());
164 EXPECT_B2FATAL(StoreObjPtr<EventMetaData>("EventMetaDatas").isValid());
165
166 //getting a base class is OK
167 EXPECT_TRUE(StoreArray<TObject>("EventMetaDatas").isValid());
168 StoreObjPtr<TObject> emd("EventMetaData");
169 EXPECT_TRUE(emd.isValid());
170 EXPECT_EQ(std::string("Belle2::EventMetaData"), std::string(emd->GetName()));
171 }
172
174 TEST_F(DataStoreTest, MetaDataTest)
175 {
177 EXPECT_EQ(evtPtr.getDurability(), DataStore::c_Event);
178 EXPECT_TRUE(evtPtr.getName() == "EventMetaData");
179 EXPECT_FALSE(evtPtr.isArray());
180 EXPECT_TRUE(evtPtr.getClass() == EventMetaData::Class());
181
183 StoreArray<EventMetaData> evtData2("EventMetaDatas");
184 StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
185 StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
186 EXPECT_TRUE(evtData.getName() == "EventMetaDatas");
187 EXPECT_TRUE(evtData.isArray());
188 EXPECT_TRUE(evtData.getClass() == EventMetaData::Class());
189 EXPECT_EQ(evtData.getDurability(), DataStore::c_Event);
190 EXPECT_TRUE(evtData == evtData2);
191 EXPECT_FALSE(evtData != evtData2);
192 EXPECT_FALSE(evtData == evtDataDifferentName);
193 EXPECT_FALSE(evtData == evtDataDifferentDurability);
194
195 //different type
196 StoreArray<ProfileInfo> profileInfo{};
197 EXPECT_FALSE(profileInfo == evtData);
198 EXPECT_TRUE(profileInfo != evtData);
199 //note: EXPECT_NE/EQ do things I don't understand. this doesn't work:
200 //EXPECT_NE(profileInfo, evtData);
201 }
202
204 TEST_F(DataStoreTest, ReadOnlyAttach)
205 {
207 EXPECT_TRUE(a);
208 EXPECT_EQ(a->getEvent(), (unsigned long)42);
210 EXPECT_FALSE(b);
212 EXPECT_FALSE(c);
214 EXPECT_FALSE(d);
215
216 //check we didn't insert a new object with 'd'
218 EXPECT_FALSE(e);
219 }
220
222 TEST_F(DataStoreTest, VerifyContents)
223 {
224 verifyContents();
225
226 //test removing data
228 evtData.clear();
229 EXPECT_TRUE(evtData.isValid());
230 EXPECT_EQ(evtData.getEntries(), 0);
231
233 evtPtr.clear(); //resets to default-constructed object
234 EXPECT_TRUE(evtPtr.isValid());
235 EXPECT_EQ(evtPtr->getEvent(), 1);
236 }
237 TEST_F(DataStoreTest, InvalidAccessor)
238 {
239 StoreArray<EventMetaData> none("doesntexist");
240 EXPECT_FALSE(none.isValid());
241 EXPECT_THROW(none.getPtr(), std::runtime_error);
242 EXPECT_THROW(none.appendNew(), std::runtime_error);
243 none.clear();
244 EXPECT_THROW(none.getPtr(), std::runtime_error);
245 EXPECT_EQ(0, none.getEntries());
246
247 StoreObjPtr<EventMetaData> noobj("doesntexist");
248 EXPECT_FALSE(noobj.isValid());
249 EXPECT_THROW(*noobj, std::runtime_error);
250 EXPECT_THROW(noobj->getEvent(), std::runtime_error);
251
252 }
253 TEST_F(DataStoreTest, RawAccess)
254 {
256 EXPECT_TRUE(evtData.getPtr() != nullptr);
257 }
258
260 TEST_F(DataStoreTest, ArrayConsistency)
261 {
263 StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
264 StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
265 StoreArray<ProfileInfo> profileInfo;
266 EXPECT_EQ((int)evtData.getPtr()->GetEntries(), 10);
267 EXPECT_EQ((int)evtDataDifferentName.getPtr()->GetEntries(), 10);
268 EXPECT_EQ((int)evtDataDifferentDurability.getPtr()->GetEntries(), 10);
269 EXPECT_EQ((int)profileInfo.getPtr()->GetEntries(), 10);
270 }
271
273 TEST_F(DataStoreTest, RangeCheck)
274 {
276 EXPECT_TRUE(evtData[0] != nullptr);
277 EXPECT_THROW(evtData[-1], std::out_of_range);
278 EXPECT_THROW(evtData[10], std::out_of_range);
279 }
280
282 TEST_F(DataStoreTest, ClearMaps)
283 {
285 EXPECT_EQ(evtPtr->getEvent(), (unsigned long)42);
286
287 //clear event map (evtPtr is now invalid!)
289
290 //right now this is NULL, since no object was actually created yet
292 EXPECT_FALSE(a);
293
295 EXPECT_FALSE(b);
296
297 //create() should produce a default constructed object
298 b.create();
299 EXPECT_TRUE(*b == EventMetaData());
300 //since a should attach to same object...
301 EXPECT_TRUE(*a == *b);
302
303 a->setEvent(42);
304 //don't replace existing object
305 a.create(false);
306 EXPECT_EQ(a->getEvent(), (unsigned long)42);
307 //replace existing object
308 a.create(true);
309 EXPECT_NE(a->getEvent(), (unsigned long)42);
310
311
312 //cleared arrays must be empty
314 StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
315 StoreArray<ProfileInfo> profileInfo;
316 EXPECT_EQ(evtData.getEntries(), 0);
317 EXPECT_EQ(evtDataDifferentName.getEntries(), 0);
318 EXPECT_EQ(profileInfo.getEntries(), 0);
319
320 //run durability, should be unaffected
321 StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
322 EXPECT_EQ(evtDataDifferentDurability.getEntries(), 10);
323 }
324
326 TEST_F(DataStoreTest, RequireObjects)
327 {
329 EXPECT_TRUE(StoreObjPtr<EventMetaData>().isRequired());
330 EXPECT_FALSE(StoreObjPtr<EventMetaData>("", DataStore::c_Persistent).isRequired());
331 EXPECT_FALSE(StoreObjPtr<EventMetaData>("nonexisting2").isRequired());
332 EXPECT_FALSE(StoreObjPtr<EventMetaData>("", DataStore::c_Persistent).isRequired());
333 //check we didn't create one...
334 EXPECT_FALSE(StoreObjPtr<EventMetaData>("nonexisting2").isRequired());
335
336 EXPECT_TRUE(StoreArray<EventMetaData>().isRequired());
337 EXPECT_TRUE(StoreArray<EventMetaData>("EventMetaDatas_2").isRequired());
338 EXPECT_TRUE(StoreArray<EventMetaData>("", DataStore::c_Persistent).isRequired());
339 EXPECT_FALSE(StoreArray<EventMetaData>("blah").isRequired());
340 EXPECT_FALSE(StoreArray<EventMetaData>("blah").isRequired());
341 EXPECT_TRUE(StoreArray<ProfileInfo>().isRequired());
342 //check we didn't create one...
343 EXPECT_FALSE(StoreArray<EventMetaData>("blah").isRequired());
345
346 EXPECT_B2FATAL(StoreObjPtr<EventMetaData>().isRequired());
347 }
348
350 TEST_F(DataStoreTest, StoreArrayIteration)
351 {
352 const StoreArray<EventMetaData> evtData;
353 StoreArray<EventMetaData> evtDataNonConst;
354 //array syntax
355 for (int i = 0; i < evtData.getEntries(); i++) {
356 EXPECT_TRUE(evtData[i] != nullptr);
357 }
358
359 //basic iterator features
360 {
361 //input iterator:
362 StoreArray<EventMetaData>::iterator it = evtDataNonConst.begin();
364 it2 = it;
365
366 //equality/inequality
367 EXPECT_TRUE(it == it2);
368 EXPECT_FALSE(it != it2);
369
370 //test postfix
371 EXPECT_TRUE((it++) == it2);
372 ++it2;
373
374 //test prefix
375 EXPECT_TRUE(it != (++it2));
376
377 //rvalue deref
378 EventMetaData ev = *it;
379 it->getEvent();
380 it2 = it;
381
382 //output iterator:
383 //lvalue deref (just overwrite with same object)
384 *it = ev;
385 *it++ = ev;
386
387 EXPECT_TRUE(ev == *it2);
388 EXPECT_TRUE(it2 != it); //was incremented
389 EXPECT_TRUE(ev != *it); //was incremented
390
391 //forward iterator (default constructor and multi-pass):
393 it3 = it;
394 ev = *it++;
395 EXPECT_TRUE(ev == *it3);
396 }
397
398 //algorithm stuff
399 {
400 StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
401 EXPECT_EQ((int)evtDataNonConst[0]->getEvent(), 10);
402 EXPECT_EQ((int)evtDataDifferentName[0]->getEvent(), 20);
403 //swap all members of evtDataNonConst ande evtDataDifferentName (same length!)
404 std::swap_ranges(evtDataNonConst.begin(), evtDataNonConst.end(), evtDataDifferentName.begin());
405 EXPECT_EQ((int)evtDataDifferentName[9]->getEvent(), 19);
406 EXPECT_EQ((int)evtDataNonConst[9]->getEvent(), 29);
407
408 //undo
409 std::swap_ranges(evtDataDifferentName.begin(), evtDataDifferentName.end(), evtDataNonConst.begin());
410 EXPECT_EQ((int)evtDataNonConst[9]->getEvent(), 19);
411 EXPECT_EQ((int)evtDataDifferentName[9]->getEvent(), 29);
412 }
413
414 int i = 0;
415 for (StoreArray<EventMetaData>::iterator it = evtDataNonConst.begin(); it != evtDataNonConst.end(); ++it) {
416 EXPECT_TRUE(&(*it) == evtData[i]);
417 EXPECT_EQ((int)it->getEvent(), 10 + i);
418 i++;
419 }
420 EXPECT_EQ(i, evtData.getEntries());
421
422 //range-based for
423 i = 0;
424 for (EventMetaData& emd : evtDataNonConst) {
425 EXPECT_TRUE(&emd == evtData[i]);
426 i++;
427 }
428 EXPECT_EQ(i, evtData.getEntries());
429
430 //range-based for (const)
431 i = 0;
432 for (const EventMetaData& emd : evtData) {
433 EXPECT_TRUE(&emd == evtData[i]);
434 i++;
435 }
436 EXPECT_EQ(i, evtData.getEntries());
437
438 //iteration over registered, but empty array
439 i = 0;
440 StoreArray<EventMetaData> evtDataEmpty("Empty");
441 for (const EventMetaData& emd : evtDataEmpty) {
442 (void)emd;
443 i++;
444 }
445 EXPECT_EQ(i, 0);
446 //iteration over non-existing array
447 i = 0;
448 StoreArray<EventMetaData> nonexistent("doesntexist");
449 for (const EventMetaData& emd : nonexistent) {
450 (void)emd;
451 i++;
452 }
453 EXPECT_EQ(i, 0);
454 }
455
457 TEST_F(DataStoreTest, DataStoreRegistration)
458 {
459 //emulate Module::initialize()
461
462 StoreObjPtr<EventMetaData> evtPtr("abc123");
463 StoreArray<EventMetaData> evtArray("abc123array");
464
465 //verify that they aren't registered right now
466 EXPECT_FALSE(evtPtr.isOptional());
467 EXPECT_FALSE(evtArray.isOptional());
468 EXPECT_FALSE(evtPtr.isRequired());
469 EXPECT_FALSE(evtArray.isRequired());
470 EXPECT_FALSE(evtPtr.isValid());
471 EXPECT_FALSE(evtArray.isValid());
472 EXPECT_FALSE(StoreObjPtr<EventMetaData>(evtPtr.getName()).isRequired());
473 EXPECT_FALSE(StoreArray<EventMetaData>(evtArray.getName()).isRequired());
474
475 EXPECT_TRUE(evtPtr.registerInDataStore());
476 EXPECT_TRUE(evtArray.registerInDataStore(DataStore::c_DontWriteOut));
477
478 //already registered, ok by default
479 EXPECT_TRUE(evtPtr.registerInDataStore());
480 EXPECT_TRUE(evtArray.registerInDataStore(DataStore::c_DontWriteOut));
481
482 //test c_ErrorIfAlreadyRegistered (return code=false + B2ERROR)
483 EXPECT_B2ERROR(EXPECT_FALSE(evtPtr.registerInDataStore(DataStore::c_ErrorIfAlreadyRegistered)));
484 EXPECT_B2ERROR(EXPECT_FALSE(evtArray.registerInDataStore(DataStore::c_DontWriteOut | DataStore::c_ErrorIfAlreadyRegistered)));
485
486 //now they should be available:
487 EXPECT_TRUE(evtPtr.isOptional());
488 EXPECT_TRUE(evtArray.isOptional());
489 EXPECT_TRUE(evtPtr.isRequired());
490 EXPECT_TRUE(evtArray.isRequired());
491 EXPECT_FALSE(evtPtr.isValid()); // not valid until created
492 EXPECT_TRUE(evtArray.isValid());
493 EXPECT_TRUE(StoreObjPtr<EventMetaData>(evtPtr.getName()).isRequired());
494 EXPECT_TRUE(StoreArray<EventMetaData>(evtArray.getName()).isRequired());
496 }
497
498 TEST_F(DataStoreTest, RegistrationOutsideOfInitializeShouldFail)
499 {
500 //outside initialize(), registration results in an error
501 EXPECT_B2ERROR(StoreArray<EventMetaData>().registerInDataStore("someothernewname"));
502 EXPECT_B2ERROR(StoreArray<EventMetaData>().registerInDataStore("someothernewname", DataStore::c_DontWriteOut));
503 EXPECT_FALSE(StoreArray<EventMetaData>().isOptional("someothernewname"));
504
505 //accessing unregistered things doesn't work.
506 StoreArray<EventMetaData> someothernewname("someothernewname");
507 EXPECT_FALSE(someothernewname.isValid());
508 }
509
510 TEST_F(DataStoreTest, ConstructedBeforeInitializeButWithNonDefaultName)
511 {
512 //as a class member, the classes get constructed before initialize(), but we may not have the name yet
515 StoreArray<EventMetaData> eventsMetaDatas2;
516
517 //initialize(), use names from module paramateres
519 {
520 EXPECT_TRUE(events.registerInDataStore("ThisBeInterestingNameForEvents"));
521 EXPECT_TRUE(profile.registerInDataStore("MyProfileInfoName", DataStore::c_DontWriteOut));
522
523 //also should work with optional / required
524 EXPECT_TRUE(eventsMetaDatas2.isOptional("EventMetaDatas_2"));
525 EXPECT_TRUE(eventsMetaDatas2.isRequired("EventMetaDatas_2"));
526 }
528
529 //ok, our objects should now know their name
530 EXPECT_EQ("ThisBeInterestingNameForEvents", events.getName());
531 EXPECT_TRUE(profile.getName() == "MyProfileInfoName");
532 EXPECT_TRUE(profile.notWrittenOut());
533 EXPECT_TRUE(eventsMetaDatas2.getName() == "EventMetaDatas_2");
534
535 //accessing data
536 EXPECT_EQ(0, events.getEntries());
537 EXPECT_FALSE(profile.isValid());
538 EXPECT_EQ(10, eventsMetaDatas2.getEntries());
539
540 //saving data
541 profile.create();
542 EXPECT_TRUE(profile.isValid());
543 StoreObjPtr<ProfileInfo> profileAttachAgain("MyProfileInfoName");
544 EXPECT_TRUE(profileAttachAgain.isValid());
545
546 events.appendNew();
547 EXPECT_EQ(1, events.getEntries());
548 StoreArray<EventMetaData> eventsAttachAgain("ThisBeInterestingNameForEvents");
549 EXPECT_EQ(1, eventsAttachAgain.getEntries());
550 }
551
552 TEST_F(DataStoreTest, ArrayList)
553 {
554 std::vector<std::string> arrayList = StoreArray<EventMetaData>::getArrayList();
555 std::vector<std::string> exparrayList = {"Empty", "EventMetaDatas", "EventMetaDatas_2"};
556 EXPECT_EQ(exparrayList, arrayList);
557 }
558
559 TEST_F(DataStoreTest, ReplaceData)
560 {
562 StoreObjPtr<EventMetaData> evtPtrB("abc123");
564 StoreArray<EventMetaData> evtDataB("otherArray");
566 evtPtrB.registerInDataStore(DataStore::c_DontWriteOut);
567 evtDataB.registerInDataStore(DataStore::c_DontWriteOut);
569
570 {
571 //objects
572 EXPECT_EQ(42, evtPtr->getEvent());
573 EXPECT_FALSE(evtPtrB.isValid());
574 EXPECT_FALSE(evtPtr.notWrittenOut());
575 EXPECT_TRUE(evtPtrB.notWrittenOut());
576
577 DataStore::Instance().replaceData(evtPtr, evtPtrB);
578 EXPECT_EQ(42, evtPtrB->getEvent());
579 EXPECT_FALSE(evtPtr.isValid());
580
581 //metadata unchanged
582 EXPECT_FALSE(evtPtr.notWrittenOut());
583 EXPECT_TRUE(evtPtrB.notWrittenOut());
584
585 //move null object into existing one
586 DataStore::Instance().replaceData(evtPtr, evtPtrB);
587 EXPECT_FALSE(evtPtr.isValid());
588 EXPECT_FALSE(evtPtrB.isValid());
589
590 //null object to null object
591 DataStore::Instance().replaceData(evtPtr, evtPtrB);
592 EXPECT_FALSE(evtPtr.isValid());
593 EXPECT_FALSE(evtPtrB.isValid());
594 }
595
596 {
597 //arrays
598 EXPECT_EQ(10, evtData.getEntries());
599 EXPECT_EQ(0, evtDataB.getEntries());
600
601 DataStore::Instance().replaceData(evtData, evtDataB);
602 EXPECT_EQ(0, evtData.getEntries());
603 EXPECT_EQ(10, evtDataB.getEntries());
604
605 DataStore::Instance().replaceData(evtData, evtDataB);
606 EXPECT_EQ(0, evtData.getEntries());
607 EXPECT_EQ(0, evtDataB.getEntries());
608
609 DataStore::Instance().replaceData(evtData, evtDataB);
610 EXPECT_EQ(0, evtData.getEntries());
611 EXPECT_EQ(0, evtDataB.getEntries());
612 }
613 }
614
615 TEST_F(DataStoreTest, SwitchDataStore)
616 {
617 EXPECT_TRUE("" == DataStore::Instance().currentID());
618 //not created yet
619 EXPECT_THROW(DataStore::Instance().copyContentsTo("foo"), std::out_of_range);
620
621 //create new DS ID
623 EXPECT_TRUE("" == DataStore::Instance().currentID());
625 EXPECT_TRUE("" == DataStore::Instance().currentID());
626 verifyContents();
628 EXPECT_TRUE("foo" == DataStore::Instance().currentID());
629 verifyContents(); //still unmodified
630
631 //change something
633 a->setEvent(1234567);
634
635 //and restore
637 EXPECT_TRUE("" == DataStore::Instance().currentID());
638 verifyContents(); //back to normal
639
640 //register another object in ""
641 //and try copying (this catches insufficient checks during copying)
642 StoreArray<EventMetaData> evtDataB("otherArray");
644 evtDataB.registerInDataStore();
646 }
647
648 TEST_F(DataStoreTest, FindStoreEntry)
649 {
650 DataStore::StoreEntry* entry = nullptr;
651 int index = -1;
652
653 //test TObject-derived arrays
655 StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
656
657 EXPECT_TRUE(DataStore::Instance().findStoreEntry(evtData[5], entry, index));
658 EXPECT_EQ(index, 5);
659 EXPECT_EQ(entry->name, evtData.getName());
660
661 //entry and index are already correct, should return quickly
662 EXPECT_TRUE(DataStore::Instance().findStoreEntry(evtData[5], entry, index));
663 EXPECT_EQ(index, 5);
664 EXPECT_EQ(entry->name, evtData.getName());
665
666 //not resetting entry, index here. this should not usually happen, but ought to be harmless
667 EXPECT_TRUE(DataStore::Instance().findStoreEntry(evtDataDifferentName[7], entry, index));
668 EXPECT_EQ(index, 7);
669 EXPECT_EQ(entry->name, evtDataDifferentName.getName());
670
671 entry = nullptr; index = -1;
672 EXPECT_TRUE(DataStore::Instance().findStoreEntry(evtDataDifferentName[7], entry, index));
673 EXPECT_EQ(index, 7);
674 EXPECT_EQ(entry->name, evtDataDifferentName.getName());
675
676 entry = nullptr; index = -1;
677 EventMetaData localObj;
678 EXPECT_FALSE(DataStore::Instance().findStoreEntry(&localObj, entry, index));
679 EXPECT_EQ(index, -1);
680 EXPECT_EQ(entry, nullptr);
681
682
683 //test RelationsObjects (caches used)
685 StoreArray<RelationsObject> relObjs2("relobs2");
687 relObjs.registerInDataStore();
688 relObjs2.registerInDataStore();
690 for (int i = 0; i < 6; i++) {
691 relObjs.appendNew();
692 relObjs2.appendNew();
693 }
694
695 entry = nullptr; index = -1;
696 EXPECT_TRUE(DataStore::Instance().findStoreEntry(relObjs[5], entry, index));
697 EXPECT_EQ(index, 5);
698 EXPECT_EQ(entry->name, relObjs.getName());
699
700 //should use cache now
701 entry = nullptr; index = -1;
702 EXPECT_TRUE(DataStore::Instance().findStoreEntry(relObjs[5], entry, index));
703 EXPECT_EQ(index, 5);
704 EXPECT_EQ(entry->name, relObjs.getName());
705
706 entry = nullptr; index = -1;
707 EXPECT_TRUE(DataStore::Instance().findStoreEntry(relObjs2[2], entry, index));
708 EXPECT_EQ(index, 2);
709 EXPECT_EQ(entry->name, relObjs2.getName());
710
711 //and caches again
712 entry = nullptr; index = -1;
713 EXPECT_TRUE(DataStore::Instance().findStoreEntry(relObjs2[2], entry, index));
714 EXPECT_EQ(index, 2);
715 EXPECT_EQ(entry->name, relObjs2.getName());
716
717 //test finding storeobjptr (not implemented, so nothing found)
719 entry = nullptr; index = -1;
720 EXPECT_FALSE(DataStore::Instance().findStoreEntry(&(*evtPtr), entry, index));
721 EXPECT_EQ(index, -1);
722 EXPECT_EQ(entry, nullptr);
723
724 //searching for nullptr is allowed
725 EXPECT_FALSE(DataStore::Instance().findStoreEntry(nullptr, entry, index));
726 }
727
728 TEST_F(DataStoreTest, ListEntries)
729 {
731 EXPECT_EQ(0, DataStore::Instance().getListOfRelatedArrays(evtData).size());
732
734 StoreArray<ProfileInfo> profileInfo;
735 evtData.registerRelationTo(profileInfo);
737
738 EXPECT_TRUE(DataStore::Instance().hasRelation(evtData, profileInfo, DataStore::c_Event, ""));
739 EXPECT_FALSE(DataStore::Instance().hasRelation(profileInfo, evtData, DataStore::c_Event, ""));
740 EXPECT_FALSE(DataStore::Instance().hasRelation(evtData, profileInfo, DataStore::c_Event, "SOMENONSENSE"));
741 EXPECT_FALSE(DataStore::Instance().hasRelation(evtData, profileInfo, DataStore::c_Persistent, ""));
742 EXPECT_FALSE(DataStore::Instance().hasRelation(profileInfo, evtData, DataStore::c_Persistent, ""));
743
744 EXPECT_EQ(1, DataStore::Instance().getListOfRelatedArrays(evtData).size());
745 EXPECT_EQ(1, DataStore::Instance().getListOfRelatedArrays(profileInfo).size());
746
747 EXPECT_EQ(1, DataStore::Instance().getListOfArrays(ProfileInfo::Class(), DataStore::c_Event).size());
748 EXPECT_EQ(0, DataStore::Instance().getListOfArrays(ProfileInfo::Class(), DataStore::c_Persistent).size());
749 EXPECT_EQ(1, DataStore::Instance().getListOfArrays(EventMetaData::Class(), DataStore::c_Persistent).size());
750 EXPECT_EQ(3, DataStore::Instance().getListOfArrays(EventMetaData::Class(), DataStore::c_Event).size());
751
752 EXPECT_EQ(1, DataStore::Instance().getListOfArrays(TObject::Class(), DataStore::c_Persistent).size());
753 EXPECT_EQ(4, DataStore::Instance().getListOfArrays(TObject::Class(), DataStore::c_Event).size());
754
755 EXPECT_EQ(1, DataStore::Instance().getListOfObjects(EventMetaData::Class(), DataStore::c_Event).size());
756 EXPECT_EQ(0, DataStore::Instance().getListOfObjects(EventMetaData::Class(), DataStore::c_Persistent).size());
757 EXPECT_EQ(1, DataStore::Instance().getListOfObjects(TObject::Class(), DataStore::c_Event).size());
758 EXPECT_EQ(0, DataStore::Instance().getListOfObjects(TObject::Class(), DataStore::c_Persistent).size());
759 }
760
761 TEST_F(DataStoreTest, Assign)
762 {
764 EXPECT_FALSE(evtData.assign(new EventMetaData(), true));
765 EXPECT_FALSE(evtData.assign(new EventMetaData(), false));
766
767 EXPECT_TRUE(evtData.isValid());
768 EXPECT_EQ(evtData.getEntries(), 10);
769
771 auto* newobj = new EventMetaData();
772 newobj->setEvent(123);
773 EXPECT_FALSE(evtPtr.assign(new EventMetaData(), false));
774 EXPECT_FALSE(evtPtr.assign(new ProfileInfo(), true));
775 EXPECT_EQ(evtPtr->getEvent(), 42);
776 EXPECT_TRUE(evtPtr.assign(newobj, true));
777 EXPECT_EQ(evtPtr->getEvent(), 123);
778 }
779} // namespace
static std::string objectName(const TClass *t, const std::string &name)
Return the storage name for an object of the given TClass and name.
Definition DataStore.cc:150
void createNewDataStoreID(const std::string &id)
creates new datastore with given id, copying the registered objects/arrays from the current one.
Definition DataStore.cc:778
static std::string defaultArrayName(const std::string &classname)
Return the default storage name for an given class name.
Definition DataStore.h:143
static std::string defaultObjectName(const std::string &classname)
Return the default storage name for given class name.
Definition DataStore.cc:127
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
Definition DataStore.h:71
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition DataStore.h:72
void switchID(const std::string &id)
switch to DataStore with given ID.
Definition DataStore.cc:793
static TClass * getTClassFromDefaultArrayName(const std::string &arrayName)
Tries to deduce the TClass from a default array name, which is generally the name of the C++ class wi...
Definition DataStore.cc:115
static TClass * getTClassFromDefaultObjectName(const std::string &objectName)
Tries to deduce the TClass from a default object name, which is generally the name of the C++ class.
Definition DataStore.cc:104
static std::string defaultRelationName()
Return the default storage name for a relation between the given types.
Definition DataStore.h:173
void copyContentsTo(const std::string &id, const std::vector< std::string > &entrylist_event={})
copy contents (actual array / object contents) of current DataStore to the DataStore with given ID.
Definition DataStore.cc:809
@ c_Persistent
Object is available during entire execution time.
Definition DataStore.h:60
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
Definition DataStore.h:59
Belle2::StoreEntry StoreEntry
Wraps a stored array/object, stored under unique (name, durability) key.
Definition DataStore.h:84
static DataStore & Instance()
Instance of singleton Store.
Definition DataStore.cc:53
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition DataStore.cc:93
static std::string relationName(const std::string &fromName, const std::string &toName, std::string const &namedRelation="")
Return storage name for a relation between two arrays of the given names.
Definition DataStore.h:180
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition DataStore.cc:85
void invalidateData(EDurability durability)
Clears all registered StoreEntry objects of a specified durability, invalidating all objects.
Definition DataStore.cc:714
static std::string arrayName(const TClass *t, const std::string &name)
Return the storage name for an object of the given TClass and name.
Definition DataStore.cc:163
void replaceData(const StoreAccessorBase &from, const StoreAccessorBase &to)
For two StoreAccessors of same type, move all data in 'from' into 'to', discarding previous contents ...
Definition DataStore.cc:342
Store event, run, and experiment numbers.
void setEvent(unsigned int event)
Event Setter.
Store execution time and memory usage.
Definition ProfileInfo.h:22
DataStore::EDurability getDurability() const
Return durability with which the object is saved in the DataStore.
const std::string & getName() const
Return name under which the object is saved in the DataStore.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool notWrittenOut() const
Returns true if this object/array should not be saved by output modules.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
virtual void clear()
Clear contents of this object.
bool assign(TObject *object, bool replace=false)
Assign 'object' to this accessor.
TClass * getClass() const
The underlying object's type.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool create(bool replace=false)
Create a default object in the data store.
bool isArray() const
Is this an accessor for an array?
Accessor to arrays stored in the data store.
Definition StoreArray.h:113
static std::vector< std::string > getArrayList(DataStore::EDurability durability=DataStore::c_Event)
Return list of array names with matching type.
Definition StoreArray.h:275
T * appendNew()
Construct a new T object at the end of the array.
Definition StoreArray.h:246
bool isValid() const
Check whether the array was registered.
Definition StoreArray.h:288
TClonesArray * getPtr() const
Raw access to the underlying TClonesArray.
Definition StoreArray.h:311
ObjArrayIterator< TClonesArray, T > iterator
STL-like iterator over the T objects (not T* ).
Definition StoreArray.h:116
int getEntries() const
Get the number of objects in the array.
Definition StoreArray.h:216
iterator end()
Return iterator to last entry +1.
Definition StoreArray.h:320
iterator begin()
Return iterator to first entry.
Definition StoreArray.h:318
void clear() override
Delete all entries in this array.
Definition StoreArray.h:207
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition StoreArray.h:140
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
bool isValid() const
Check whether the object was created.
bool isValid(EForwardBackward eForwardBackward)
Check whether the given enum instance is one of the valid values.
Abstract base class for different kinds of events.
STL namespace.
std::string name
Name of the entry.
Definition StoreEntry.h:53