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
214 const char* format()
const {
215 return match->era.format();
220 logging::printf(
"Transition(");
227 logging::printf(
"; UTC");
233 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
235 logging::printf(
"; rule=-");
237 logging::printf(
"; rule=");
238 logging::printf(
"[%d,%d]", rule.fromYear(), rule.toYear());
252 uint16_t minutes = seconds / 60;
253 uint8_t second = seconds - minutes * int32_t(60);
254 uint8_t hour = minutes / 60;
255 uint8_t minute = minutes - hour * 60;
257 logging::printf(
"%c%02u:%02u", sign, (
unsigned) hour, (
unsigned) minute);
259 logging::printf(
"%c%02u:%02u:%02u",
260 sign, (
unsigned) hour, (
unsigned) minute, (
unsigned) second);
264 #ifdef ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
271 logging::printf(prefix);
273 logging::printf(
"\n");
286 template <
typename ZEB,
typename ZPB,
typename ZRB>
316 template <
typename ZEB,
typename ZPB,
typename ZRB>
360 template<u
int8_t SIZE,
typename ZEB,
typename ZPB,
typename ZRB>
393 for (uint8_t i = 0; i < SIZE; i++) {
394 mTransitions[i] = &mPool[i];
397 mIndexCandidates = 0;
403 return mTransitions[mIndexPrior];
415 mIndexCandidates = mIndexPrior;
416 mIndexFree = mIndexPrior;
420 return &mTransitions[mIndexCandidates];
423 return &mTransitions[mIndexFree];
427 return &mTransitions[0];
430 return &mTransitions[mIndexFree];
439 if (mIndexFree < SIZE) {
441 if (mIndexFree >= mAllocSize) {
442 mAllocSize = mIndexFree + 1;
444 return mTransitions[mIndexFree];
450 return mTransitions[SIZE - 1];
462 if (mIndexFree >= SIZE)
return;
464 mIndexPrior = mIndexFree;
465 mIndexCandidates = mIndexFree;
481 return &mTransitions[mIndexPrior];
487 Transition* prior = mTransitions[mIndexPrior];
492 internal::swap(mTransitions[mIndexPrior], mTransitions[mIndexFree]);
512 if (mIndexFree >= SIZE)
return;
521 for (uint8_t i = mIndexFree; i > mIndexCandidates; i--) {
525 mTransitions[i] = prev;
526 mTransitions[i - 1] = curr;
538 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
539 logging::printf(
"addActiveCandidatesToActivePool()\n");
543 uint8_t iActive = mIndexPrior;
544 uint8_t iCandidate = mIndexCandidates;
545 for (; iCandidate < mIndexFree; iCandidate++) {
546 if (isCompareStatusActive(mTransitions[iCandidate]->compareStatus)) {
547 if (iActive != iCandidate) {
550 internal::swap(mTransitions[iActive], mTransitions[iCandidate]);
556 mIndexPrior = iActive;
557 mIndexCandidates = iActive;
558 mIndexFree = iActive;
560 return mTransitions[iActive - 1];
573 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
575 "findTransitionForSeconds(): mIndexFree: %d\n", mIndexFree);
581 for (uint8_t i = 0; i < mIndexFree; i++) {
582 next = mTransitions[i];
606 if (curr ==
nullptr) {
614 if (prev ==
nullptr) {
620 acetime_t shiftSeconds = subtractDateTuple(
622 if (shiftSeconds >= 0) {
637 if (next ==
nullptr) {
643 acetime_t shiftSeconds = subtractDateTuple(
645 if (shiftSeconds >= 0) {
685 for (uint8_t i = 0; i < mIndexFree; i++) {
686 curr = mTransitions[i];
690 bool isExactMatch = (startDateTime <= localDate)
691 && (localDate < untilDateTime);
702 }
else if (startDateTime > localDate) {
726 logging::printf(
"TransitionStorage: ");
727 logging::printf(
"SIZE=%d, mAllocSize=%d\n", SIZE, mAllocSize);
728 int nActives = mIndexPrior;
729 int nPrior = mIndexCandidates - mIndexPrior;
730 int nCandidates = mIndexFree - mIndexCandidates;
731 int nAllocFree = mAllocSize - mIndexFree;
732 int nVirginFree = SIZE - mAllocSize;
734 logging::printf(
" Actives: %d\n", nActives);
736 " ", &mTransitions[0], &mTransitions[mIndexPrior]);
738 logging::printf(
" Prior: %d\n", nPrior);
740 " ", &mTransitions[mIndexPrior], &mTransitions[mIndexCandidates]);
742 logging::printf(
" Candidates: %d\n", nCandidates);
744 " ", &mTransitions[mIndexCandidates], &mTransitions[mIndexFree]);
746 logging::printf(
" Allocated Free: %d\n", nAllocFree);
747 logging::printf(
" Virgin Free: %d\n", nVirginFree);
761 friend class ::TransitionStorageTest_getFreeAgent;
762 friend class ::TransitionStorageTest_getFreeAgent2;
763 friend class ::TransitionStorageTest_addFreeAgentToActivePool;
764 friend class ::TransitionStorageTest_reservePrior;
765 friend class ::TransitionStorageTest_addPriorToCandidatePool;
766 friend class ::TransitionStorageTest_addFreeAgentToCandidatePool;
767 friend class ::TransitionStorageTest_setFreeAgentAsPriorIfValid;
768 friend class ::TransitionStorageTest_addActiveCandidatesToActivePool;
769 friend class ::TransitionStorageTest_findTransitionForDateTime;
770 friend class ::TransitionStorageTest_resetCandidatePool;
774 return mTransitions[i];
780 uint8_t mIndexCandidates;
784 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 base offset minutes, not the total effective UTC 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.