6 #ifndef ACE_TIME_EXTENDED_TRANSITION_H
7 #define ACE_TIME_EXTENDED_TRANSITION_H
10 #include "common/logging.h"
11 #include "local_date_mutation.h"
12 #include "DateTuple.h"
14 class TransitionStorageTest_getFreeAgent;
15 class TransitionStorageTest_getFreeAgent2;
16 class TransitionStorageTest_addFreeAgentToActivePool;
17 class TransitionStorageTest_reservePrior;
18 class TransitionStorageTest_addPriorToCandidatePool;
19 class TransitionStorageTest_addFreeAgentToCandidatePool;
20 class TransitionStorageTest_setFreeAgentAsPriorIfValid;
21 class TransitionStorageTest_addActiveCandidatesToActivePool;
22 class TransitionStorageTest_findTransitionForDateTime;
23 class TransitionStorageTest_resetCandidatePool;
27 #ifndef ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
28 #define ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG 0
34 inline bool isCompareStatusActive(CompareStatus status) {
35 return status == CompareStatus::kExactMatch
36 || status == CompareStatus::kWithinMatch
37 || status == CompareStatus::kPrior;
46 template<
typename ZEB>
70 logging::printf(
"MatchingEra(");
73 logging::printf(
"; era=%c", (
era.isNull()) ?
'-' :
'*');
74 logging::printf(
"; prevMatch=%c", (
prevMatch) ?
'*' :
'-');
113 template <
typename ZEB,
typename ZPB,
typename ZRB>
119 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
167 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
212 const char* format()
const {
213 return match->era.format();
218 logging::printf(
"Transition(");
225 logging::printf(
"; UTC");
231 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
233 logging::printf(
"; rule=-");
235 logging::printf(
"; rule=");
236 logging::printf(
"[%d,%d]", rule.fromYear(), rule.toYear());
250 uint8_t hour = minutes / 60;
251 uint8_t minute = minutes - hour * 60;
252 logging::printf(
"%c%02u:%02u", sign, (
unsigned) hour, (
unsigned) minute);
255 #ifdef ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
262 logging::printf(prefix);
264 logging::printf(
"\n");
277 template <
typename ZEB,
typename ZPB,
typename ZRB>
307 template <
typename ZEB,
typename ZPB,
typename ZRB>
351 template<u
int8_t SIZE,
typename ZEB,
typename ZPB,
typename ZRB>
384 for (uint8_t i = 0; i < SIZE; i++) {
385 mTransitions[i] = &mPool[i];
388 mIndexCandidates = 0;
394 return mTransitions[mIndexPrior];
406 mIndexCandidates = mIndexPrior;
407 mIndexFree = mIndexPrior;
411 return &mTransitions[mIndexCandidates];
414 return &mTransitions[mIndexFree];
418 return &mTransitions[0];
421 return &mTransitions[mIndexFree];
430 if (mIndexFree < SIZE) {
432 if (mIndexFree >= mAllocSize) {
433 mAllocSize = mIndexFree + 1;
435 return mTransitions[mIndexFree];
441 return mTransitions[SIZE - 1];
453 if (mIndexFree >= SIZE)
return;
455 mIndexPrior = mIndexFree;
456 mIndexCandidates = mIndexFree;
472 return &mTransitions[mIndexPrior];
478 Transition* prior = mTransitions[mIndexPrior];
483 internal::swap(mTransitions[mIndexPrior], mTransitions[mIndexFree]);
503 if (mIndexFree >= SIZE)
return;
512 for (uint8_t i = mIndexFree; i > mIndexCandidates; i--) {
516 mTransitions[i] = prev;
517 mTransitions[i - 1] = curr;
529 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
530 logging::printf(
"addActiveCandidatesToActivePool()\n");
534 uint8_t iActive = mIndexPrior;
535 uint8_t iCandidate = mIndexCandidates;
536 for (; iCandidate < mIndexFree; iCandidate++) {
537 if (isCompareStatusActive(mTransitions[iCandidate]->compareStatus)) {
538 if (iActive != iCandidate) {
541 internal::swap(mTransitions[iActive], mTransitions[iCandidate]);
547 mIndexPrior = iActive;
548 mIndexCandidates = iActive;
549 mIndexFree = iActive;
551 return mTransitions[iActive - 1];
564 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
566 "findTransitionForSeconds(): mIndexFree: %d\n", mIndexFree);
572 for (uint8_t i = 0; i < mIndexFree; i++) {
573 next = mTransitions[i];
597 if (curr ==
nullptr) {
605 if (prev ==
nullptr) {
611 acetime_t shiftSeconds = subtractDateTuple(
613 if (shiftSeconds >= 0) {
628 if (next ==
nullptr) {
634 acetime_t shiftSeconds = subtractDateTuple(
636 if (shiftSeconds >= 0) {
676 for (uint8_t i = 0; i < mIndexFree; i++) {
677 curr = mTransitions[i];
681 bool isExactMatch = (startDateTime <= localDate)
682 && (localDate < untilDateTime);
693 }
else if (startDateTime > localDate) {
717 logging::printf(
"TransitionStorage: ");
718 logging::printf(
"SIZE=%d, mAllocSize=%d\n", SIZE, mAllocSize);
719 int nActives = mIndexPrior;
720 int nPrior = mIndexCandidates - mIndexPrior;
721 int nCandidates = mIndexFree - mIndexCandidates;
722 int nAllocFree = mAllocSize - mIndexFree;
723 int nVirginFree = SIZE - mAllocSize;
725 logging::printf(
" Actives: %d\n", nActives);
727 " ", &mTransitions[0], &mTransitions[mIndexPrior]);
729 logging::printf(
" Prior: %d\n", nPrior);
731 " ", &mTransitions[mIndexPrior], &mTransitions[mIndexCandidates]);
733 logging::printf(
" Candidates: %d\n", nCandidates);
735 " ", &mTransitions[mIndexCandidates], &mTransitions[mIndexFree]);
737 logging::printf(
" Allocated Free: %d\n", nAllocFree);
738 logging::printf(
" Virgin Free: %d\n", nVirginFree);
752 friend class ::TransitionStorageTest_getFreeAgent;
753 friend class ::TransitionStorageTest_getFreeAgent2;
754 friend class ::TransitionStorageTest_addFreeAgentToActivePool;
755 friend class ::TransitionStorageTest_reservePrior;
756 friend class ::TransitionStorageTest_addPriorToCandidatePool;
757 friend class ::TransitionStorageTest_addFreeAgentToCandidatePool;
758 friend class ::TransitionStorageTest_setFreeAgentAsPriorIfValid;
759 friend class ::TransitionStorageTest_addActiveCandidatesToActivePool;
760 friend class ::TransitionStorageTest_findTransitionForDateTime;
761 friend class ::TransitionStorageTest_resetCandidatePool;
765 return mTransitions[i];
771 uint8_t mIndexCandidates;
775 uint8_t mAllocSize = 0;
Class that holds the date-time as the components (year, month, day, hour, minute, second) without reg...
uint8_t day() const
Return the day of the month.
uint8_t month() const
Return the month with January=1, December=12.
uint8_t minute() const
Return the minute.
uint8_t hour() const
Return the hour.
int16_t year() const
Return the year.
A heap manager which is specialized and tuned to manage a collection of Transitions,...
void resetAllocSize()
Reset the current allocation size.
void addFreeAgentToActivePool()
Immediately add the free agent Transition at index mIndexFree to the Active pool.
TransitionForSecondsTemplate< ZEB, ZPB, ZRB > TransitionForSeconds
Template instantiation of TransitionForSecondsTemplate used by this class.
TransitionForDateTimeTemplate< ZEB, ZPB, ZRB > TransitionForDateTime
Template instantiation of TransitionForDateTimeTemplate used by this class.
void init()
Initialize all pools to 0 size, usually when a new year is initialized.
void setFreeAgentAsPriorIfValid()
Set the free agent transition as the most recent prior.
Transition * getFreeAgent()
Return a pointer to the first Transition in the free pool.
TransitionTemplate< ZEB, ZPB, ZRB > Transition
Template instantiation of TransitionTemplate used by this class.
void resetCandidatePool()
Empty the Candidate pool by resetting the various indexes.
static void calcFoldAndOverlap(uint8_t *fold, uint8_t *num, const Transition *prev, const Transition *curr, const Transition *next, acetime_t epochSeconds)
Calculate the fold and num parameters of TransitionForSecond.
uint8_t getAllocSize() const
Return the maximum number of transitions which was allocated.
void addFreeAgentToCandidatePool()
Add the free agent Transition at index mIndexFree to the Candidate pool, sorted by transitionTime.
Transition * getPrior()
Return the current prior transition.
TransitionForDateTime findTransitionForDateTime(const LocalDateTime &ldt) const
Return the candidate Transitions matching the given dateTime.
TransitionStorageTemplate()
Constructor.
Transition * addActiveCandidatesToActivePool()
Add active candidates into the Active pool, and collapse the Candidate pool.
void addPriorToCandidatePool()
Add the current prior into the Candidates pool.
TransitionForSeconds findTransitionForSeconds(acetime_t epochSeconds) const
Return the Transition matching the given epochSeconds.
Transition ** reservePrior()
Allocate a free Transition then add it to the Prior pool.
void log() const
Verify that the indexes are valid.
int32_t acetime_t
Type for the number of seconds from epoch.
A tuple that represents a date and time.
void log() const
Used only for debugging.
Data structure that captures the matching ZoneEra and its ZoneRule transitions for a given year.
MatchingEraTemplate * prevMatch
The previous MatchingEra, needed to interpret startDateTime.
int16_t lastDeltaMinutes
The DST offset of the last Transition in this MatchingEra.
ZEB era
The ZoneEra that matched the given year.
DateTuple untilDateTime
The effective until time of the matching ZoneEra.
DateTuple startDateTime
The effective start time of the matching ZoneEra, which uses the UTC offsets of the previous matching...
int16_t lastOffsetMinutes
The STD offset of the last Transition in this MatchingEra.
The result of the findTransitionForDateTime(const LocalDatetime& ldt) method which can return 0,...
uint8_t num
Number of matches: 0, 1, 2.
const TransitionTemplate< ZEB, ZPB, ZRB > * prev
The previous transition.
const TransitionTemplate< ZEB, ZPB, ZRB > * curr
The matching transition, or null if not found or in gap.
Tuple of a matching Transition and its 'fold'.
uint8_t fold
1 if corresponding datetime occurred the second time
const TransitionTemplate< ZEB, ZPB, ZRB > * curr
The matching transition, or null if not found.
uint8_t num
Number of occurrences of the resulting LocalDateTime: 0, 1, or 2.
Represents an interval of time where the time zone obeyed a certain UTC offset and DST delta.
static void printTransitions(const char *prefix, const TransitionTemplate *const *begin, const TransitionTemplate *const *end)
Print an iterable of Transitions from 'begin' to 'end'.
bool isValidPrior
During findCandidateTransitions(), this flag indicates whether the current transition is a valid "pri...
DateTuple transitionTime
The original transition time, usually 'w' but sometimes 's' or 'u'.
acetime_t startEpochSeconds
The calculated transition time of the given rule.
DateTuple transitionTimeS
Version of transitionTime in 's' mode, using the UTC offset of the previous Transition.
DateTuple untilDateTime
Until time expressed using the UTC offset of the current Transition.
const char * letter
Storage for the 'letter' field if 'rule' is not null.
int16_t offsetMinutes
The base offset minutes, not the total effective UTC offset.
void log() const
Used only for debugging.
DateTuple transitionTimeU
Version of transitionTime in 'u' mode, using the UTC offset of the previous transition.
CompareStatus compareStatus
During processTransitionCompareStatus(), this flag indicates how the transition falls within the time...
static void logHourMinute(int16_t minutes)
Print minutes as [+/-]hh:mm.
DateTuple startDateTime
Start time expressed using the UTC offset of the current Transition.
char abbrev[internal::kAbbrevSize]
The calculated effective time zone abbreviation, e.g.
int16_t deltaMinutes
The DST delta minutes.
const MatchingEraTemplate< ZEB > * match
The match which generated this Transition.
static const uint8_t kSuffixW
Represents 'w' or wall time.