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;
58 typename D::ZoneEraBroker
era;
70 logging::printf(
"MatchingEra(");
73 logging::printf(
"; era=%c", (
era.isNull()) ?
'-' :
'*');
74 logging::printf(
"; prevMatch=%c", (
prevMatch) ?
'*' :
'-');
111 template <
typename D>
117 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
124 typename D::ZoneRuleBroker rule;
165 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
206 const char* format()
const {
207 return match->era.format();
212 logging::printf(
"Transition(");
219 logging::printf(
"; UTC");
225 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
227 logging::printf(
"; rule=-");
229 logging::printf(
"; rule=");
230 logging::printf(
"[%d,%d]", rule.fromYear(), rule.toYear());
244 uint16_t minutes = seconds / 60;
245 uint8_t second = seconds - minutes * int32_t(60);
246 uint8_t hour = minutes / 60;
247 uint8_t minute = minutes - hour * 60;
249 logging::printf(
"%c%02u:%02u", sign, (
unsigned) hour, (
unsigned) minute);
251 logging::printf(
"%c%02u:%02u:%02u",
252 sign, (
unsigned) hour, (
unsigned) minute, (
unsigned) second);
256 #ifdef ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
263 logging::printf(prefix);
265 logging::printf(
"\n");
278 template <
typename D>
308 template <
typename D>
350 template<u
int8_t SIZE,
typename D>
383 for (uint8_t i = 0; i < SIZE; i++) {
384 mTransitions[i] = &mPool[i];
387 mIndexCandidates = 0;
393 return mTransitions[mIndexPrior];
405 mIndexCandidates = mIndexPrior;
406 mIndexFree = mIndexPrior;
410 return &mTransitions[mIndexCandidates];
413 return &mTransitions[mIndexFree];
417 return &mTransitions[0];
420 return &mTransitions[mIndexFree];
429 if (mIndexFree < SIZE) {
431 if (mIndexFree >= mAllocSize) {
432 mAllocSize = mIndexFree + 1;
434 return mTransitions[mIndexFree];
440 return mTransitions[SIZE - 1];
452 if (mIndexFree >= SIZE)
return;
454 mIndexPrior = mIndexFree;
455 mIndexCandidates = mIndexFree;
471 return &mTransitions[mIndexPrior];
477 Transition* prior = mTransitions[mIndexPrior];
482 swap(mTransitions[mIndexPrior], mTransitions[mIndexFree]);
502 if (mIndexFree >= SIZE)
return;
511 for (uint8_t i = mIndexFree; i > mIndexCandidates; i--) {
515 mTransitions[i] = prev;
516 mTransitions[i - 1] = curr;
528 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
529 logging::printf(
"addActiveCandidatesToActivePool()\n");
533 uint8_t iActive = mIndexPrior;
534 uint8_t iCandidate = mIndexCandidates;
535 for (; iCandidate < mIndexFree; iCandidate++) {
536 if (isCompareStatusActive(mTransitions[iCandidate]->compareStatus)) {
537 if (iActive != iCandidate) {
540 swap(mTransitions[iActive], mTransitions[iCandidate]);
546 mIndexPrior = iActive;
547 mIndexCandidates = iActive;
548 mIndexFree = iActive;
550 return mTransitions[iActive - 1];
563 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
565 "findTransitionForSeconds(): mIndexFree: %d\n", mIndexFree);
571 for (uint8_t i = 0; i < mIndexFree; i++) {
572 next = mTransitions[i];
614 if (curr ==
nullptr) {
622 if (prev ==
nullptr) {
628 acetime_t shiftSeconds = subtractDateTuple(
630 if (shiftSeconds >= 0) {
645 if (next ==
nullptr) {
651 acetime_t shiftSeconds = subtractDateTuple(
653 if (shiftSeconds >= 0) {
693 for (uint8_t i = 0; i < mIndexFree; i++) {
694 curr = mTransitions[i];
698 bool isExactMatch = (startDateTime <= localDate)
699 && (localDate < untilDateTime);
710 }
else if (startDateTime > localDate) {
734 logging::printf(
"TransitionStorage: ");
735 logging::printf(
"SIZE=%d, mAllocSize=%d\n", SIZE, mAllocSize);
736 int nActives = mIndexPrior;
737 int nPrior = mIndexCandidates - mIndexPrior;
738 int nCandidates = mIndexFree - mIndexCandidates;
739 int nAllocFree = mAllocSize - mIndexFree;
740 int nVirginFree = SIZE - mAllocSize;
742 logging::printf(
" Actives: %d\n", nActives);
744 " ", &mTransitions[0], &mTransitions[mIndexPrior]);
746 logging::printf(
" Prior: %d\n", nPrior);
748 " ", &mTransitions[mIndexPrior], &mTransitions[mIndexCandidates]);
750 logging::printf(
" Candidates: %d\n", nCandidates);
752 " ", &mTransitions[mIndexCandidates], &mTransitions[mIndexFree]);
754 logging::printf(
" Allocated Free: %d\n", nAllocFree);
755 logging::printf(
" Virgin Free: %d\n", nVirginFree);
769 friend class ::TransitionStorageTest_getFreeAgent;
770 friend class ::TransitionStorageTest_getFreeAgent2;
771 friend class ::TransitionStorageTest_addFreeAgentToActivePool;
772 friend class ::TransitionStorageTest_reservePrior;
773 friend class ::TransitionStorageTest_addPriorToCandidatePool;
774 friend class ::TransitionStorageTest_addFreeAgentToCandidatePool;
775 friend class ::TransitionStorageTest_setFreeAgentAsPriorIfValid;
776 friend class ::TransitionStorageTest_addActiveCandidatesToActivePool;
777 friend class ::TransitionStorageTest_findTransitionForDateTime;
778 friend class ::TransitionStorageTest_resetCandidatePool;
782 return mTransitions[i];
788 uint8_t mIndexCandidates;
792 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 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< D > Transition
Template instantiation of TransitionTemplate used by this class.
void addPriorToCandidatePool()
Add the current prior into the Candidates pool.
uint8_t getAllocSize() const
Return the maximum number of transitions which was allocated.
Transition * addActiveCandidatesToActivePool()
Add active candidates into the Active pool, and collapse the Candidate pool.
void resetCandidatePool()
Empty the Candidate pool by resetting the various indexes.
void resetAllocSize()
Reset the current allocation size.
void addFreeAgentToActivePool()
Immediately add the free agent Transition at index mIndexFree to the Active pool.
TransitionForSecondsTemplate< D > TransitionForSeconds
Template instantiation of TransitionForSecondsTemplate used by this class.
TransitionForDateTimeTemplate< D > TransitionForDateTime
Template instantiation of TransitionForDateTimeTemplate used by this class.
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.
Transition * getPrior()
Return the current prior transition.
TransitionStorageTemplate()
Constructor.
TransitionForDateTime findTransitionForDateTime(const LocalDateTime &ldt) const
Return the candidate Transitions matching the given dateTime.
void addFreeAgentToCandidatePool()
Add the free agent Transition at index mIndexFree to the Candidate pool, sorted by transitionTime.
Transition ** reservePrior()
Allocate a free Transition then add it to the Prior pool.
TransitionForSeconds findTransitionForSeconds(acetime_t epochSeconds) const
Return the Transition matching the given epochSeconds.
void init()
Initialize all pools to 0 size, usually when a new year is initialized.
void log() const
Verify that the indexes are valid.
void swap(T &a, T &b)
Swap 2 parameters.
const uint8_t kAbbrevSize
Size of the c-string buffer needed to hold a time zone abbreviation.
int32_t acetime_t
Type for the number of seconds from epoch.
static const uint8_t kSuffixW
Represents 'w' or wall time.
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.
int32_t lastDeltaSeconds
The DST offset of the last Transition in this MatchingEra.
MatchingEraTemplate * prevMatch
The previous MatchingEra, needed to interpret startDateTime.
DateTuple startDateTime
The effective start time of the matching ZoneEra, which uses the UTC offsets of the previous matching...
int32_t lastOffsetSeconds
The STD offset of the last Transition in this MatchingEra.
DateTuple untilDateTime
The effective until time of the matching ZoneEra.
D::ZoneEraBroker era
The ZoneEra that matched the given year.
The result of the findTransitionForDateTime(const LocalDatetime& ldt) method which can return 0,...
const TransitionTemplate< D > * curr
The matching transition, or null if not found or in gap.
const TransitionTemplate< D > * prev
The previous transition.
uint8_t num
Number of matches: 0, 1, 2.
Tuple of a matching Transition and its 'fold'.
const TransitionTemplate< D > * curr
The matching transition, or null if not found.
uint8_t num
Number of occurrences of the resulting LocalDateTime: 0, 1, or 2.
uint8_t fold
1 if corresponding datetime occurred the second time
Represents an interval of time where the time zone obeyed a certain UTC offset and DST delta.
static void logHourMinuteSecond(int32_t seconds)
Print seconds as [+/-]hh:mm[:ss].
DateTuple transitionTimeU
Version of transitionTime in 'u' mode, using the UTC offset of the previous transition.
void log() const
Used only for debugging.
DateTuple transitionTime
The original transition time, usually 'w' but sometimes 's' or 'u'.
const MatchingEraTemplate< D > * match
The match which generated this Transition.
DateTuple startDateTime
Start time expressed using the UTC offset of the current Transition.
CompareStatus compareStatus
During processTransitionCompareStatus(), this flag indicates how the transition falls within the time...
int32_t deltaSeconds
The DST delta seconds.
bool isValidPrior
During findCandidateTransitions(), this flag indicates whether the current transition is a valid "pri...
char abbrev[kAbbrevSize]
The calculated effective time zone abbreviation, e.g.
acetime_t startEpochSeconds
The calculated transition time of the given rule.
DateTuple untilDateTime
Until time expressed using the UTC offset of the current Transition.
static void printTransitions(const char *prefix, const TransitionTemplate *const *begin, const TransitionTemplate *const *end)
Print an iterable of Transitions from 'begin' to 'end'.
DateTuple transitionTimeS
Version of transitionTime in 's' mode, using the UTC offset of the previous Transition.
int32_t offsetSeconds
The standard time offset seconds, not the total offset.