1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * ALICE Experiment at CERN, All rights reserved. *
5 * Primary Authors: Artur Szostak <artursz@iafrica.com> *
6 * for The ALICE HLT Project. *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
17 /// @file AliHLTTriggerDomain.cxx
18 /// @author Artur Szostak <artursz@iafrica.com>
20 /// @brief Implementation of the AliHLTTriggerDomain class.
22 /// The trigger domain class is the set of HLT raw data block types that should
23 /// be readout and sent to HLTOUT.
25 #include "AliHLTTriggerDomain.h"
26 #include "AliHLTDomainEntry.h"
27 #include "Riostream.h"
29 ClassImp(AliHLTTriggerDomain)
32 AliHLTTriggerDomain::AliHLTTriggerDomain() :
33 TObject(), fEntries(AliHLTDomainEntry::Class(), 10)
35 // Default constructor.
39 AliHLTTriggerDomain::AliHLTTriggerDomain(const AliHLTTriggerDomain& domain) :
41 fEntries(AliHLTDomainEntry::Class(), domain.fEntries.GetEntriesFast())
43 // Copy constructor performs a deep copy.
44 // See header file for more details.
46 for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
48 const AliHLTDomainEntry* entry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
49 new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(*entry);
54 AliHLTTriggerDomain::~AliHLTTriggerDomain()
56 // Default destructor.
60 void AliHLTTriggerDomain::Add(const AliHLTDomainEntry& entry)
62 // Adds a new domain entry to the trigger domain.
63 // See header file for more details.
65 AliHLTDomainEntry intersect;
66 bool alreadyInSet = false;
68 // Get the initial size of the fEntries array since we might add things to the
69 // end during the calculation.
70 Int_t count = fEntries.GetEntriesFast();
72 // Go through each entry that is already in fEntries and see if we can remove
73 // it because it will become redundant, or if we need to patch exclusion entries
74 // by adding inclusive intersects, or if we do not even need to add the new entry
75 // because it is already part of the trigger domain.
76 for (Int_t i = 0; i < count; i++)
78 AliHLTDomainEntry* ientry = static_cast<AliHLTDomainEntry*>(fEntries[i]);
79 if (ientry->Inclusive())
81 if (entry.SubsetOf(*ientry))
85 else if (ientry->SubsetOf(entry))
87 ientry->SetBit(14, true); // mark for removal.
92 if (ientry->SubsetOf(entry))
94 ientry->SetBit(14, true); // mark for removal.
96 else if (entry.SubsetOf(*ientry))
100 else if (ientry->IntersectWith(entry, intersect))
102 MarkForDeletionSubsetsOf(intersect, count);
103 new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(kFALSE, intersect);
108 // Check if we need to add the new entry.
109 if (not alreadyInSet)
111 MarkForDeletionSubsetsOf(entry, count);
112 new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(kFALSE, entry);
114 RemoveMarkedEntries();
118 void AliHLTTriggerDomain::Add(const AliHLTComponentDataType& datatype)
120 // Adds a new domain entry with the given data type to the trigger domain.
121 // But the data block specification is set to the any matching wild card.
122 // See header file for more details.
124 Add(AliHLTDomainEntry(datatype));
128 void AliHLTTriggerDomain::Add(const char* blocktype, const char* origin)
130 // Adds a new domain entry with the given data type and origin to the trigger domain.
131 // But the data block specification is set to the any matching wild card.
132 // See header file for more details.
134 Add(AliHLTDomainEntry(blocktype, origin));
138 void AliHLTTriggerDomain::Add(const AliHLTComponentDataType& datatype, UInt_t spec)
140 // Adds a new domain entry to the trigger domain with the data type and data block
141 // specification bits.
142 // See header file for more details.
144 Add(AliHLTDomainEntry(datatype, spec));
148 void AliHLTTriggerDomain::Add(const char* blocktype, const char* origin, UInt_t spec)
150 // Adds a new domain entry to the trigger domain with the given data type, origin
151 // and data block specification bits.
152 // See header file for more details.
154 Add(AliHLTDomainEntry(blocktype, origin, spec));
158 void AliHLTTriggerDomain::Remove(const AliHLTDomainEntry& entry)
160 // Removes the given domain entry from the trigger domain.
161 // See header file for more details.
163 AliHLTDomainEntry intersect;
164 bool addToExcludeSet = false;
166 // Get the initial size of the fEntries array since we might add things to the
167 // end during the calculation.
168 Int_t count = fEntries.GetEntriesFast();
170 // We need to go through all existing entries and see if they need to be removed
171 // because they would become redundant when we add the new 'entry' to the end of
172 // the fEntries list. We also need to check if the new entry needs to be added
173 // at all because the trigger domain might already not contain those entries.
174 // Lastly, some intersection entries might need to be added to patch up existing
175 // inclusive trigger domain entries (rules / patterns).
176 for (Int_t i = 0; i < count; i++)
178 AliHLTDomainEntry* ientry = static_cast<AliHLTDomainEntry*>(fEntries[i]);
179 if (ientry->Inclusive())
181 if (ientry->SubsetOf(entry))
183 ientry->SetBit(14, true); // mark for removal.
185 else if (entry.SubsetOf(*ientry))
187 addToExcludeSet = true;
189 else if (ientry->IntersectWith(entry, intersect))
191 new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(kTRUE, intersect);
196 if (entry.SubsetOf(*ientry))
198 addToExcludeSet = false;
200 else if (ientry->SubsetOf(entry))
202 ientry->SetBit(14, true); // mark for removal.
207 // Check if we need to add the new entry.
210 MarkForDeletionSubsetsOf(entry, count);
211 new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(kTRUE, entry);
213 RemoveMarkedEntries();
217 void AliHLTTriggerDomain::Remove(const AliHLTComponentDataType& datatype)
219 // Removes the domain entries that have the given data type from the trigger domain.
220 // See header file for more details.
222 Remove(AliHLTDomainEntry(datatype));
226 void AliHLTTriggerDomain::Remove(const char* blocktype, const char* origin)
228 // Removes the domain entries that have the given data type and origin from the
230 // See header file for more details.
232 Remove(AliHLTDomainEntry(blocktype, origin));
236 void AliHLTTriggerDomain::Remove(const AliHLTComponentDataType& datatype, UInt_t spec)
238 // Removes the domain entries that have the given data type and data block
239 // specification bits from the trigger domain.
240 // See header file for more details.
242 Remove(AliHLTDomainEntry(datatype, spec));
246 void AliHLTTriggerDomain::Remove(const char* blocktype, const char* origin, UInt_t spec)
248 // Removes the domain entries that have the given data type, origin and data
249 // block specification bits from the trigger domain.
250 // See header file for more details.
252 Remove(AliHLTDomainEntry(blocktype, origin, spec));
256 bool AliHLTTriggerDomain::Contains(const AliHLTDomainEntry& entry) const
258 // Checks to see if the given domain entry is part of the trigger domain set.
259 // See header file for more details.
261 // Simply go through the whole list of fEntries and for each entry see if the
262 // given domain entry 'entry' being checked matches. If there is a match then
263 // update the result depending on the entry type. i.e. set to false if the entry
264 // in fEntries is an exclusion and set to true if it is an inclusion.
266 for (Int_t i = 0; i < fEntries.GetEntriesFast(); i++)
268 const AliHLTDomainEntry* ientry = static_cast<const AliHLTDomainEntry*>(fEntries[i]);
269 if (ientry->Inclusive())
271 if (*ientry == entry) result = true;
275 if (entry.SubsetOf(*ientry)) result = false;
282 bool AliHLTTriggerDomain::IncludeInReadout(const AliHLTComponentBlockData* block) const
284 // Checks to see if the given data block is part of the trigger domain set and
285 // should be readout.
286 // See header file for more details.
288 // Same algorithm as for Contains() but applied directly to the data block
289 // descriptor structure.
290 AliHLTDomainEntry blockEntry(block->fDataType, block->fSpecification);
292 for (Int_t i = 0; i < fEntries.GetEntriesFast(); i++)
294 const AliHLTDomainEntry* entry = static_cast<const AliHLTDomainEntry*>(fEntries[i]);
295 if (entry->Inclusive())
297 if (*entry == block) result = true;
301 if (blockEntry.SubsetOf(*entry)) result = false;
308 void AliHLTTriggerDomain::Clear(Option_t* option)
310 // Clears the trigger domain (Removes all entries).
312 fEntries.Clear(option);
316 void AliHLTTriggerDomain::Print(Option_t* /*option*/) const
318 // Prints the trigger domain entries in the order that they are applied.
319 // See header file for more details.
321 cout << "Trigger domain rules (applied in order of first to last):" << endl;
322 for (Int_t i = 0; i < fEntries.GetEntriesFast(); i++)
324 const AliHLTDomainEntry* entry = static_cast<const AliHLTDomainEntry*>( fEntries[i] );
325 if (entry->Inclusive())
335 if (fEntries.GetEntriesFast() == 0)
337 cout << "(empty)" << endl;
342 AliHLTTriggerDomain& AliHLTTriggerDomain::operator = (const AliHLTTriggerDomain& domain)
344 // Assignment operator performs a deep copy.
345 // See header file for more details.
347 if (this == &domain) return *this;
348 TObject::operator = (domain);
350 for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
352 const AliHLTDomainEntry* entry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
353 new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(*entry);
359 AliHLTTriggerDomain& AliHLTTriggerDomain::operator |= (const AliHLTTriggerDomain& domain)
361 // This operator performs the set union.
362 // See header file for more details.
364 // Note that we partition the fEntries array into 3 regions for this calculation.
365 // - 0..entriesCount-1 : contains the initial entries of this trigger domain.
366 // - entriesCount..startOfIntersects-1 : is space reserved for the new entries
368 // - startOfIntersects..fEntries.GetEntriesFast()-1 : This will grow as we add
369 // all the new domain intersections created during the calculation.
371 // Get the number of entries now before we start adding more entries from 'domain'.
372 Int_t count = fEntries.GetEntriesFast();
373 // Mark the start location for new intersection entries.
374 Int_t startOfIntersects = count + domain.fEntries.GetEntriesFast();
375 Int_t newIndex = startOfIntersects;
377 // Allocate and initialise a single block of memory so that we do not call new twice.
378 bool* buffer = new bool[startOfIntersects];
379 for (Int_t i = 0; i < startOfIntersects; i++) buffer[i] = false;
380 bool* removeThisEntry = buffer;
381 bool* removeDomainEntry = buffer + count;
383 AliHLTDomainEntry intersect;
385 // The idea behind this algorithm is that we need to add all inclusion domain
386 // entries from 'domain' to this object that will not be redundant, but for
387 // the exclusion entries we patch the fEntries rule set by adding the appropriate
388 // intersections to the end of fEntries.
389 for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
391 const AliHLTDomainEntry* newEntry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
392 for (Int_t j = 0; j < count; j++)
394 const AliHLTDomainEntry* currentEntry = static_cast<const AliHLTDomainEntry*>( fEntries[j] );
395 if (currentEntry->Inclusive() and newEntry->Inclusive())
397 // If either entry is a subset of the other then we do not need to add
398 // both, so make sure to remove the one that is redundant.
399 if (newEntry->SubsetOf(*currentEntry))
401 removeDomainEntry[i] = true;
403 else if (currentEntry->SubsetOf(*newEntry))
405 removeThisEntry[j] = true;
410 if (newEntry->IntersectWith(*currentEntry, intersect))
412 // We can remove all intersections that were already added that will
413 // become redundant when this intersection is added to fEntries.
414 MarkForDeletionSubsetsOf(intersect, startOfIntersects);
416 // Make the new intersection entry an exclusion if the newEntry and
417 // currentEntry flags are the same.
418 bool exclude = newEntry->Exclusive() == currentEntry->Exclusive();
419 new (fEntries[newIndex++]) AliHLTDomainEntry(exclude, intersect);
421 // We can also remove entries that are subsets of another entry in the
422 // opposite list, since they will be redundant when everything is merged
423 // together. For example, remove entry x from fEntries if it is a subset
424 // of entry y in domain.fEntries.
425 if (currentEntry->IdenticalTo(intersect)) removeThisEntry[j] = true;
426 if (newEntry->IdenticalTo(intersect)) removeDomainEntry[i] = true;
432 MergeEntries(removeThisEntry, count, removeDomainEntry, startOfIntersects, domain);
439 AliHLTTriggerDomain& AliHLTTriggerDomain::operator ^= (const AliHLTTriggerDomain& domain)
441 // This operator performs the set union, less the set intersect (something like and xor).
442 // See header file for more details.
444 // Note that we partition the fEntries array into 3 regions for this calculation.
445 // - 0..entriesCount-1 : contains the initial entries of this trigger domain.
446 // - entriesCount..startOfIntersects-1 : is space reserved for the new entries
448 // - startOfIntersects..fEntries.GetEntriesFast()-1 : This will grow as we add
449 // all the new domain intersections created during the calculation.
451 // Get the number of entries now before we start adding more entries from 'domain'.
452 Int_t count = fEntries.GetEntriesFast();
453 // Mark the start location for new intersection entries.
454 Int_t startOfIntersects = count + domain.fEntries.GetEntriesFast();
455 Int_t newIndex = startOfIntersects;
457 // Allocate and initialise a single block of memory so that we do not call new twice.
458 bool* buffer = new bool[startOfIntersects];
459 for (Int_t i = 0; i < startOfIntersects; i++) buffer[i] = false;
460 bool* removeThisEntry = buffer;
461 bool* removeDomainEntry = buffer + count;
463 AliHLTDomainEntry intersect;
465 // This algorithm is similar to the case for the set union (operator |=), except
466 // that we make sure to remove from the trigger domain all parts where the entries
467 // from fEntries and domain.fEntries intersect.
468 // This is done by adding the intersections to the end of fEntries such that they
469 // effectively remove those overlapping trigger domain entries when calculating
470 // IncludeInReadout() or Contains().
471 for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
473 const AliHLTDomainEntry* newEntry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
474 for (Int_t j = 0; j < count; j++)
476 const AliHLTDomainEntry* currentEntry = static_cast<const AliHLTDomainEntry*>( fEntries[j] );
477 if (newEntry->IntersectWith(*currentEntry, intersect))
479 // We can remove all intersections that were already added that will
480 // become redundant when this intersection is added to fEntries.
481 MarkForDeletionSubsetsOf(intersect, startOfIntersects);
483 // Make the new intersection entry an exclusion if the newEntry and
484 // currentEntry flags are the same.
485 bool exclude = newEntry->Exclusive() == currentEntry->Exclusive();
486 new (fEntries[newIndex++]) AliHLTDomainEntry(exclude, intersect);
488 // We can also remove entries that are subsets of another entry in the
489 // opposite list, since they will be redundant when everything is merged
490 // together. For example, remove entry x from fEntries if it is a subset
491 // of entry y in domain.fEntries.
492 if (currentEntry->IdenticalTo(intersect)) removeThisEntry[j] = true;
493 if (newEntry->IdenticalTo(intersect)) removeDomainEntry[i] = true;
498 MergeEntries(removeThisEntry, count, removeDomainEntry, startOfIntersects, domain);
505 AliHLTTriggerDomain& AliHLTTriggerDomain::operator -= (const AliHLTTriggerDomain& domain)
507 // This operator performs the set difference.
508 // See header file for more details.
510 // Mark the number of entries in fEntries now before we start adding more
511 // entries from 'domain' or intersections.
512 Int_t startOfIntersects = fEntries.GetEntriesFast();
513 Int_t newIndex = startOfIntersects;
515 AliHLTDomainEntry intersect;
517 // To compute the set difference we need to remove all all parts that overlap
518 // with 'domain'. i.e. we need to find all the intersects between the domain
519 // entries in fEntries and those in domain.fEntries, and add the intersects
520 // to the fEntries list, such that they will cancel or remove the overlapping
521 // parts of the two trigger domains.
522 for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
524 const AliHLTDomainEntry* checkEntry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
525 if (checkEntry->Inclusive())
527 // For inclusive entries we need to find the overlaps with the inclusive
528 // entries in fEntries and add exclusive entries that will remove that
529 // part of the trigger domain set.
530 for (Int_t j = 0; j < startOfIntersects; j++)
532 AliHLTDomainEntry* currentEntry = static_cast<AliHLTDomainEntry*>( fEntries[j] );
534 // We only need to consider the case where both entries are inclusive,
535 // since an exclusion in fEntries already eliminates those data blocks
536 // from the trigger domain set.
537 if (currentEntry->Exclusive()) continue;
539 if (checkEntry->IntersectWith(*currentEntry, intersect))
541 // We can remove all intersections that were already added that will
542 // become redundant when this intersection is added to fEntries.
543 MarkForDeletionSubsetsOf(intersect, startOfIntersects);
545 new (fEntries[newIndex++]) AliHLTDomainEntry(kTRUE, intersect);
546 if (currentEntry->IdenticalTo(intersect))
548 currentEntry->SetBit(14, true);
555 // For an exclusive entry in 'domain' we need to find the intersections with
556 // all of fEntries and re-apply these with the same exclude flags.
557 for (Int_t j = 0; j < startOfIntersects; j++)
559 AliHLTDomainEntry* currentEntry = static_cast<AliHLTDomainEntry*>( fEntries[j] );
560 if (checkEntry->IntersectWith(*currentEntry, intersect))
562 // We can remove all intersections that were already added that will
563 // become redundant when this intersection is added to fEntries.
564 MarkForDeletionSubsetsOf(intersect, startOfIntersects);
566 new (fEntries[newIndex++]) AliHLTDomainEntry(currentEntry->Exclusive(), intersect);
572 RemoveMarkedEntries();
578 AliHLTTriggerDomain AliHLTTriggerDomain::operator ~ () const
580 // Performs a set complement of the trigger domain.
582 // The set complement is calculated by creating a new trigger domain which
583 // accepts all possible data blocks, and then apply all the trigger domain
584 // entries (rules / patterns) from top to bottom, but apply them with the
585 // opposite meaning. For example, this->fEntries contains an inclusive domain
586 // entry then remove it from the new trigger domain 'result', but if it is
587 // an exclusion then add it.
588 AliHLTTriggerDomain result;
589 result.Add(kAliHLTAnyDataType);
590 for (Int_t i = 0; i < fEntries.GetEntriesFast(); i++)
592 const AliHLTDomainEntry* entry = static_cast<const AliHLTDomainEntry*>( fEntries[i] );
593 if (entry->Inclusive())
595 result.Remove(*entry);
606 AliHLTTriggerDomain AliHLTTriggerDomain::operator & (const AliHLTTriggerDomain& domain) const
608 // This operator finds the set intersect.
609 // See header file for more details.
611 AliHLTTriggerDomain result;
613 AliHLTDomainEntry intersect;
615 // To find the set intersect we need to compare each entry in 'domain' to those
616 // of fEntries. For each inclusive entry in 'domain' we need to add to the result
617 // the intersect between it and each entry of fEntries, with the same exclude flag
618 // value as the domain entry from fEntries.
619 // However, in principle, for the exclusion entries in 'domain' we just add them
620 // to the result, since those entries do not form part of the 'domain' trigger
621 // domain set, so they should not form part of the result (remember any data block
622 // must be contained in both trigger domains for a set intersect).
623 // In actual fact we just add the intersect of the exclusion entries in 'domain'
624 // with those of fEntries to the result. This has the same overall effect, but
625 // makes sure that all exclusion entries are always subsets of inclusion entries.
626 for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
628 const AliHLTDomainEntry* checkEntry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
629 if (checkEntry->Inclusive())
631 for (Int_t j = 0; j < fEntries.GetEntriesFast(); j++)
633 AliHLTDomainEntry* currentEntry = static_cast<AliHLTDomainEntry*>( fEntries[j] );
634 if (checkEntry->IntersectWith(*currentEntry, intersect))
636 // We can remove all entries that were already added to the result that
637 // will become redundent because they are subsets of the new entry.
638 result.MarkForDeletionSubsetsOf(intersect, 0);
640 new (result.fEntries[newIndex++]) AliHLTDomainEntry(currentEntry->Exclusive(), intersect);
646 for (Int_t j = 0; j < fEntries.GetEntriesFast(); j++)
648 AliHLTDomainEntry* currentEntry = static_cast<AliHLTDomainEntry*>( fEntries[j] );
649 if (checkEntry->IntersectWith(*currentEntry, intersect))
651 // We can remove all entries that were already added to the result that
652 // will become redundant because they are subsets of the new entry.
653 result.MarkForDeletionSubsetsOf(intersect, 0);
655 new (result.fEntries[newIndex++]) AliHLTDomainEntry(kTRUE, intersect);
661 result.RemoveMarkedEntries();
667 void AliHLTTriggerDomain::MergeEntries(
668 const bool* removeThisEntry, Int_t entriesCount,
669 const bool* removeDomainEntry, Int_t startOfIntersects,
670 const AliHLTTriggerDomain& domain
673 // Merges the entries in this trigger domain with the ones in 'domain', while
674 // removing all entries that were marked for removal.
675 // See header file for more information.
677 bool anythingRemoved = false;
679 // Remember this method is used at the end of the calculation of the binary operators
680 // and that fEntries is expected to be partitioned into 3 regions.
681 // - 0..entriesCount-1 : contains the original (initial) entries of this trigger domain.
682 // - entriesCount..startOfIntersects-1 : is space reserved for the new entries
683 // from the given trigger domain 'domain' being processed.
684 // - startOfIntersects..fEntries.GetEntriesFast()-1 : contains all new domain entry
685 // intersection created and added to fEntries.
687 // First we need to remove all entries marked for removal from the original entries.
688 for (Int_t i = 0; i < entriesCount; i++)
690 if (removeThisEntry[i])
692 fEntries.RemoveAt(i);
693 anythingRemoved = true;
697 // Now we copy over all the new entries from 'domain' which were not marked for removal
698 // and indicate anythingRemoved = true since there will now be gaps in the clones array
699 // that need to be compressed away later.
700 for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
702 if (removeDomainEntry[i])
704 anythingRemoved = true;
708 const AliHLTDomainEntry* newEntry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
709 new (fEntries[entriesCount+i]) AliHLTDomainEntry(*newEntry);
713 // Finally remove all new intersection entries that were marked for removal by
714 // the MarkForDeletionSubsetsOf method.
715 for (Int_t i = startOfIntersects; i < fEntries.GetEntriesFast(); i++)
717 const AliHLTDomainEntry* ientry = static_cast<const AliHLTDomainEntry*>( fEntries[i] );
718 if (ientry->TestBit(14))
720 fEntries.RemoveAt(i);
721 anythingRemoved = true;
724 if (anythingRemoved) fEntries.Compress();
728 void AliHLTTriggerDomain::MarkForDeletionSubsetsOf(const AliHLTDomainEntry& entry, Int_t min)
730 // Marks for deletion all the entries in this trigger domain that are subsets
731 // of the given entry.
732 // See header file for more information.
734 AliHLTDomainEntry intersect;
735 for (Int_t i = min; i < fEntries.GetEntriesFast(); i++)
737 AliHLTDomainEntry* ientry = static_cast<AliHLTDomainEntry*>( fEntries[i] );
738 if (ientry->TestBit(14)) continue;
739 if (ientry->SubsetOf(entry))
741 ientry->SetBit(14, true);
747 void AliHLTTriggerDomain::RemoveMarkedEntries()
749 // Removes all entries in this trigger domain which were marked for removal.
750 // See header file for more information.
752 bool anythingRemoved = false;
753 for (Int_t i = 0; i < fEntries.GetEntriesFast(); i++)
755 const AliHLTDomainEntry* ientry = static_cast<const AliHLTDomainEntry*>( fEntries[i] );
756 if (ientry->TestBit(14))
758 fEntries.RemoveAt(i);
759 anythingRemoved = true;
762 if (anythingRemoved) fEntries.Compress();
766 void AliHLTTriggerDomain::Optimise()
768 // Removes redundant trigger domain entries from the trigger domain.
769 // See header file for more information.
771 AliHLTDomainEntry intersect;
773 // Check that the first entry is not and exclusion which would be redundent.
774 if (fEntries.GetEntriesFast() == 0) return;
775 AliHLTDomainEntry* firstEntry = static_cast<AliHLTDomainEntry*>( fEntries[0] );
776 if (firstEntry->Exclusive()) firstEntry->SetBit(14, true);
778 for (Int_t i = 1; i < fEntries.GetEntriesFast(); i++)
780 AliHLTDomainEntry* ientry = static_cast<AliHLTDomainEntry*>( fEntries[i] );
782 // For the i'th entry in fEntries, compare it in reverse order with all other
783 // entries that are before it and look for redundant ones, i.e. that are subsets
784 // of the i'th entry.
785 for (Int_t j = i-1; j >= 0; j--)
787 AliHLTDomainEntry* jentry = static_cast<AliHLTDomainEntry*>( fEntries[j] );
788 if (jentry->TestBit(14)) continue;
789 // Find entries that intersect
790 if (jentry->SubsetOf(*ientry))
792 // jentry is a subset of ientry so it is redundant because for all values
793 // ientry will override jentry when calling IncludeInReadout.
794 jentry->SetBit(14, true);
796 else if (*ientry == *jentry)
798 // If intersecting entries have opposite exclude flags then search no further,
799 // we know that we will need this entry for correct behaviour of IncludeInReadout.
800 if (ientry->Inclusive() == jentry->Exclusive()) goto processNextEntry;
802 if (ientry->SubsetOf(*jentry))
804 ientry->SetBit(14, true);
805 goto processNextEntry;
810 // If we got to this point then we hit the top of the trigger domain rules
811 // (pattern matching) list without hitting any and overlapping entries.
812 // So now we need to check if ientry is an exclusion. If it is, then it is
813 // redundant and we can mark it for removal.
814 if (ientry->Exclusive()) ientry->SetBit(14, true);
819 RemoveMarkedEntries();