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
208 const char* format()
const {
209 return match->era.format();
214 logging::printf(
"Transition(");
221 logging::printf(
"; UTC");
227 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
229 logging::printf(
"; rule=-");
231 logging::printf(
"; rule=");
232 logging::printf(
"[%d,%d]", rule.fromYear(), rule.toYear());
246 uint16_t minutes = seconds / 60;
247 uint8_t second = seconds - minutes * int32_t(60);
248 uint8_t hour = minutes / 60;
249 uint8_t minute = minutes - hour * 60;
251 logging::printf(
"%c%02u:%02u", sign, (
unsigned) hour, (
unsigned) minute);
253 logging::printf(
"%c%02u:%02u:%02u",
254 sign, (
unsigned) hour, (
unsigned) minute, (
unsigned) second);
258 #ifdef ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
265 logging::printf(prefix);
267 logging::printf(
"\n");
280 template <
typename ZEB,
typename ZPB,
typename ZRB>
310 template <
typename ZEB,
typename ZPB,
typename ZRB>
354 template<u
int8_t SIZE,
typename ZEB,
typename ZPB,
typename ZRB>
387 for (uint8_t i = 0; i < SIZE; i++) {
388 mTransitions[i] = &mPool[i];
391 mIndexCandidates = 0;
397 return mTransitions[mIndexPrior];
409 mIndexCandidates = mIndexPrior;
410 mIndexFree = mIndexPrior;
414 return &mTransitions[mIndexCandidates];
417 return &mTransitions[mIndexFree];
421 return &mTransitions[0];
424 return &mTransitions[mIndexFree];
433 if (mIndexFree < SIZE) {
435 if (mIndexFree >= mAllocSize) {
436 mAllocSize = mIndexFree + 1;
438 return mTransitions[mIndexFree];
444 return mTransitions[SIZE - 1];
456 if (mIndexFree >= SIZE)
return;
458 mIndexPrior = mIndexFree;
459 mIndexCandidates = mIndexFree;
475 return &mTransitions[mIndexPrior];
481 Transition* prior = mTransitions[mIndexPrior];
486 internal::swap(mTransitions[mIndexPrior], mTransitions[mIndexFree]);
506 if (mIndexFree >= SIZE)
return;
515 for (uint8_t i = mIndexFree; i > mIndexCandidates; i--) {
519 mTransitions[i] = prev;
520 mTransitions[i - 1] = curr;
532 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
533 logging::printf(
"addActiveCandidatesToActivePool()\n");
537 uint8_t iActive = mIndexPrior;
538 uint8_t iCandidate = mIndexCandidates;
539 for (; iCandidate < mIndexFree; iCandidate++) {
540 if (isCompareStatusActive(mTransitions[iCandidate]->compareStatus)) {
541 if (iActive != iCandidate) {
544 internal::swap(mTransitions[iActive], mTransitions[iCandidate]);
550 mIndexPrior = iActive;
551 mIndexCandidates = iActive;
552 mIndexFree = iActive;
554 return mTransitions[iActive - 1];
567 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
569 "findTransitionForSeconds(): mIndexFree: %d\n", mIndexFree);
575 for (uint8_t i = 0; i < mIndexFree; i++) {
576 next = mTransitions[i];
600 if (curr ==
nullptr) {
608 if (prev ==
nullptr) {
614 acetime_t shiftSeconds = subtractDateTuple(
616 if (shiftSeconds >= 0) {
631 if (next ==
nullptr) {
637 acetime_t shiftSeconds = subtractDateTuple(
639 if (shiftSeconds >= 0) {
679 for (uint8_t i = 0; i < mIndexFree; i++) {
680 curr = mTransitions[i];
684 bool isExactMatch = (startDateTime <= localDate)
685 && (localDate < untilDateTime);
696 }
else if (startDateTime > localDate) {
720 logging::printf(
"TransitionStorage: ");
721 logging::printf(
"SIZE=%d, mAllocSize=%d\n", SIZE, mAllocSize);
722 int nActives = mIndexPrior;
723 int nPrior = mIndexCandidates - mIndexPrior;
724 int nCandidates = mIndexFree - mIndexCandidates;
725 int nAllocFree = mAllocSize - mIndexFree;
726 int nVirginFree = SIZE - mAllocSize;
728 logging::printf(
" Actives: %d\n", nActives);
730 " ", &mTransitions[0], &mTransitions[mIndexPrior]);
732 logging::printf(
" Prior: %d\n", nPrior);
734 " ", &mTransitions[mIndexPrior], &mTransitions[mIndexCandidates]);
736 logging::printf(
" Candidates: %d\n", nCandidates);
738 " ", &mTransitions[mIndexCandidates], &mTransitions[mIndexFree]);
740 logging::printf(
" Allocated Free: %d\n", nAllocFree);
741 logging::printf(
" Virgin Free: %d\n", nVirginFree);
755 friend class ::TransitionStorageTest_getFreeAgent;
756 friend class ::TransitionStorageTest_getFreeAgent2;
757 friend class ::TransitionStorageTest_addFreeAgentToActivePool;
758 friend class ::TransitionStorageTest_reservePrior;
759 friend class ::TransitionStorageTest_addPriorToCandidatePool;
760 friend class ::TransitionStorageTest_addFreeAgentToCandidatePool;
761 friend class ::TransitionStorageTest_setFreeAgentAsPriorIfValid;
762 friend class ::TransitionStorageTest_addActiveCandidatesToActivePool;
763 friend class ::TransitionStorageTest_findTransitionForDateTime;
764 friend class ::TransitionStorageTest_resetCandidatePool;
768 return mTransitions[i];
774 uint8_t mIndexCandidates;
778 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 second() const
Return the second.
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.
ZEB era
The ZoneEra that matched the given year.
DateTuple untilDateTime
The effective until time of the matching ZoneEra.
int32_t lastOffsetSeconds
The STD offset of the last Transition in this MatchingEra.
DateTuple startDateTime
The effective start time of the matching ZoneEra, which uses the UTC offsets of the previous matching...
int32_t lastDeltaSeconds
The DST 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'.
int32_t offsetSeconds
The standard time offset seconds, not the total offset.
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.
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...
int32_t deltaSeconds
The DST delta seconds.
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.
static void logHourMinuteSecond(int32_t seconds)
Print seconds as [+/-]hh:mm[:ss].
const MatchingEraTemplate< ZEB > * match
The match which generated this Transition.
static const uint8_t kSuffixW
Represents 'w' or wall time.