Skip to content

Commit 02ff26c

Browse files
authored
Merge pull request #84 from bxparks/develop
merge v1.9.0 into master
2 parents a5601c4 + f688f0d commit 02ff26c

File tree

552 files changed

+15702
-12663
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

552 files changed

+15702
-12663
lines changed

.github/workflows/aunit_tests.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@ jobs:
1616

1717
- name: Setup
1818
run: |
19+
sudo apt update
20+
sudo apt install -y libcurl4-openssl-dev
1921
cd ..
22+
git clone https://github.com/HowardHinnant/date
2023
git clone https://github.com/bxparks/EpoxyDuino
2124
git clone https://github.com/bxparks/AceRoutine
2225
git clone https://github.com/bxparks/AUnit
2326
git clone https://github.com/bxparks/AceCommon
2427
git clone https://github.com/bxparks/AceWire
28+
git clone https://github.com/bxparks/AceSorting
2529
2630
- name: Verify examples
2731
run: |

.github/workflows/validation.yml

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on: [push]
99
jobs:
1010
build:
1111

12-
runs-on: ubuntu-18.04
12+
runs-on: ubuntu-20.04
1313

1414
# Tried to use
1515
# https://github.com/actions/checkout#Checkout-multiple-repos-side-by-side,
@@ -29,14 +29,15 @@ jobs:
2929
git clone https://github.com/bxparks/EpoxyDuino
3030
git clone https://github.com/bxparks/AUnit
3131
git clone https://github.com/bxparks/AceCommon
32+
git clone https://github.com/bxparks/AceSorting
3233
git clone https://github.com/bxparks/AceTimeTools
3334
git clone https://github.com/bxparks/AceTimePython
3435
git clone https://github.com/bxparks/AceTimeValidation
3536
git clone https://github.com/eggert/tz
3637
git clone https://github.com/HowardHinnant/date
3738
3839
- name: Set up Python 3.7
39-
uses: actions/setup-python@v1
40+
uses: actions/setup-python@v2
4041
with:
4142
python-version: '3.7'
4243

@@ -60,19 +61,14 @@ jobs:
6061
run: |
6162
make -C ../AceTimeTools/compare_cpp
6263
63-
# Run just BasicHinnantDateTest and ExtendedHinnantDateTest. When a new
64-
# TZDB version comes out, the Python pytz, dateutil, and Java validation
65-
# tests will always fail because they depend on the obsolete TZ database on
66-
# the hosted Operating System.
64+
# Run the validations from AceTimeValidations (BasicHinnantDateTest,
65+
# ExtendedHinnantDateTest, BasicAcetzTest, ExtendedAcetzTest). We don't run
66+
# the others because when a new TZDB version comes out, the Python pytz,
67+
# dateutil, and Java validation tests will fail because they depend
68+
# on the obsolete TZ database on the host Operating System.
6769

68-
- name: BasicHinnantDateTest
70+
- name: AceTimeValidation
6971
run: |
7072
cd ../AceTimeValidation
71-
make -C BasicHinnantDateTest
72-
make -C BasicHinnantDateTest runtests
73-
74-
- name: ExtendedHinnantDateTest
75-
run: |
76-
cd ../AceTimeValidation
77-
make -C ExtendedHinnantDateTest
78-
make -C ExtendedHinnantDateTest runtests
73+
make validations
74+
make runvalidations

CHANGELOG.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,44 @@
11
# Changelog
22

33
* Unreleased
4+
* 1.9.0 (2021-12-02, TZDB 2021e)
5+
* Add `ZoneSorterByName` and `ZoneSorterByOffsetAndName` classes
6+
to sort zone indexes, ids, or names according to 2 pre-defined sorting
7+
criteria: (1) by name, or (2) by UTC offset and then by name.
8+
* See the [Zone Sorting](USER_GUIDE.md#ZoneSorting) section in the
9+
`USER_GUIDE.md`.
10+
* Adds a new dependency to
11+
[AceSorting](https://github.com/bxparks/AceSorting) library.
12+
* Add `examples/CompareAceTimeToHinnantDate` to compare the performance of
13+
AceTime compared to Hinnant date library.
14+
* AceTime seems to be about 90X faster for converting date-time
15+
components to epoch seconds.
16+
* Add `MaxBufSize` comment field into `zonedb[x]/zone_infos.h` which is the
17+
maximum over all zones in that file. Must be less than or equal to
18+
`ExtendedZoneProcessor::kMaxTransitions`.
19+
* **Potential Breaking Change**: `class TransitionStorage`
20+
* Rename `getHighWater()` to `getAllocSize()`. This now returns the
21+
maximum number of transitions that has been allocated so far, which
22+
happens to be `getHighWater() + 1`.
23+
* Rename `resetHighWater()` to `resetAllocSize()`.
24+
* Rename `ExtendedZoneProcessor::resetTransitionHighWater()` to
25+
`resetTransitionAllocSize()`.
26+
* All of these methods were intended for internal debugging so these
27+
changes are not considered to be an API change.
28+
* The semantics of these methods are now closer to the algorithm in
29+
`AceTimePython/zone_processor.ZoneProcessor`.
30+
* **Breaking Change**: Extract `BasicZoneProcessorCache` and
31+
`ExtendedZoneProcessorCache` out of `BasicZoneManager` and
32+
`ExtendedZoneManager`. Remove all pure `virtual` methods from
33+
`ZoneManager`, making the class hierarchy non-polymorphic.
34+
* Saves 1100-1300 bytes of flash on AVR processors.
35+
* See [Migrating to v1.9](MIGRATING.md#MigratingToVersion190) for
36+
migration info.
37+
* **Breaking Change**: Remove pure `virtual` methods from `LinkManager`,
38+
analogous to their removal from `ZoneManager`.
39+
* Saves 68 bytes of flash on AVR processors.
40+
* See [Migrating to v1.9](MIGRATING.md#MigratingToVersion190) for
41+
migration info.
442
* 1.8.2 (2021-10-28, TZDB 2021e)
543
* Update to TZDB 2021e.
644
* https://mm.icann.org/pipermail/tz-announce/2021-October/000069.html

DEVELOPER.md

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -626,16 +626,15 @@ tests will fail until the underlying timezone database of the OS is updated.
626626
<a name="ReleaseProcess"></a>
627627
## Release Process
628628

629+
* Update `examples/MemoryBenchmark` and `examples/AutoBenchmark`.
629630
* Update and commit the version numbers in various files:
630631
* `src/AceTime.h`
631632
* `README.md`
632-
* `docs/date_time_timezone.md`
633-
* `docs/clock_system_clock.md`
634-
* `docs/installation.md`
635-
* ...
633+
* `USER_GUIDE.md`
634+
* `MIGRATING.md`
635+
* `CHANGELOG.md`
636636
* `docs/doxygen.cfg`
637637
* `library.properties`
638-
* `CHANGELOG.md`
639638
* `$ git commit -m "..."`
640639
* Update and commit the Doxygen docs. This is done as a separate git commit
641640
because the Doxygen changes are often so large that they obscure all other
@@ -652,6 +651,17 @@ tests will fail until the underlying timezone database of the OS is updated.
652651
* Approve and merge the PR.
653652
* Create a new Release of AceTimePython.
654653
* Go to https://github.com/bxparks/AceTimePython
654+
* Bump version number on `develop`.
655+
* Merge `develop` into `master`.
656+
* Click on "Releases"
657+
* Click on "Draft a new release"
658+
* Enter a tag version (e.g. `v1.2`), targeting the `master` branch.
659+
* Enter the release title.
660+
* Enter the release notes. I normally just copy and paste the latest changes
661+
from `CHANGELOG.md`.
662+
* Click Publish release.
663+
* Create a new Release of AceTimeTools.
664+
* Go to https://github.com/bxparks/AceTimeTools
655665
* Click on "Releases"
656666
* Click on "Draft a new release"
657667
* Enter a tag version (e.g. `v1.2`), targeting the `master` branch.
@@ -668,10 +678,14 @@ tests will fail until the underlying timezone database of the OS is updated.
668678
* Enter the release notes. I normally just copy and paste the latest changes
669679
from `CHANGELOG.md`.
670680
* Click Publish release.
671-
* Add corresponding tags on AceTimeTools and AceTimeValidation for reference.
681+
* Add corresponding tags on AceTimePython, AceTimeTools and AceTimeValidation
682+
for reference.
672683
* AceTimePython
673684
* `$ git tag -a 'atX.Y.Z' -m 'AceTime vX.Y.Z'`
674685
* `$ git push --tags`
686+
* AceTimeTools
687+
* `$ git tag -a 'atX.Y.Z' -m 'AceTime vX.Y.Z'`
688+
* `$ git push --tags`
675689
* AceTimeValidation
676690
* `$ git tag -a 'atX.Y.Z' -m 'AceTime vX.Y.Z'`
677691
* `$ git push --tags`

MIGRATING.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,184 @@
22

33
## Table of Contents
44

5+
* [Migrating to v1.9.0](#MigratingToVersion190)
6+
* [Configuring the Zone Managers](#ConfiguringZoneManagers)
7+
* [Using the Zone Managers](#UsingZoneManagers)
8+
* [Link Managers](#LinkManagers)
59
* [Migrating to v1.8.0](#MigratingToVersion180)
610
* [Migrating to AceTimeClock](#MigratingToAceTimeClock)
711
* [Migrating the DS3231Clock](#MigratingTheDS3231Clock)
812
* [Migrating to LinkManagers](#MigratingToLinkManagers)
913

14+
<a name="MigratingToVersion190"></a>
15+
## Migrating to v1.9.0
16+
17+
The `ZoneManager` hierarchy (containing `ManualZoneManager`, `BasicZoneManager`,
18+
and `ExtendedZoneManager`) was refactored from v1.8.0 to v1.9.0.
19+
20+
<a name="ConfiguringZoneManagers"></a>
21+
### Configuring the Zone Managers
22+
23+
In v1.8, the `ZoneManager` was an abstract interface class with 7 pure virtual
24+
methods that was the base class of the class hierarchy of all ZoneManager
25+
subclasses. This was convenient because the `TimeZone` related parts of the
26+
client application code could be written against the `ZoneManager` base class
27+
and the specific implementation could be configured in a small section of the
28+
application code. The problem with such a polymorphic class hierarchy is that
29+
the virtual methods consume significant amounts of flash memory, especially on
30+
8-bit AVR processors with limited flash. The
31+
[examples/MemoryBenchmark](examples/MemoryBenchmark) program showed that this
32+
design consumed an extra 1100-1300 bytes of flash.
33+
34+
In v1.9, several changes were made to reduce the flash memory size:
35+
36+
1. All virtual methods were removed from the `ZoneManager` and its
37+
subclasses.
38+
2. The `BasicZoneManager` and `ExtendedZoneManager` classes are no longer
39+
template classes, making them easier to use (e.g. in the `ZoneSorterByName`
40+
and `ZoneSorterByOffsetAndName` classes).
41+
3. The internal `BasicZoneProcessorCache` and `ExtendedZoneProcessorCache`
42+
member variables were extracted out from the respective ZoneManager classes.
43+
These are now expected to be created separately, and passed into the
44+
constructors of the `BasicZoneManager` and `ExtendedZoneManager` classes.
45+
46+
The migration path is relatively simple. In v1.8, the `BasicZoneManager` was
47+
configured like this:
48+
49+
```C++
50+
static const uint8_t CACHE_SIZE = 4;
51+
BasicZoneManager<CACHE_SIZE> zoneManager(
52+
kZoneRegistrySize,
53+
kZoneRegistry);
54+
```
55+
56+
In v1.9, this should be replaced with code that looks like:
57+
58+
```C++
59+
static const uint8_t CACHE_SIZE = 4;
60+
BasicZoneProcessorCache<CACHE_SIZE> zoneProcessorCache;
61+
BasicZoneManager zoneManager(
62+
kZoneRegistrySize,
63+
kZoneRegistry,
64+
zoneProcessorCache);
65+
```
66+
67+
Similarly, in v1.8, the `ExtendedZoneManager` was configured like following:
68+
69+
```C++
70+
static const uint8_t CACHE_SIZE = 4;
71+
ExtendedoneManager<CACHE_SIZE> zoneManager(
72+
zonedb::kZoneRegistrySize,
73+
zonedb::kZoneRegistry);
74+
```
75+
76+
In v1.9, this should be replaced with code that looks like this:
77+
78+
```C++
79+
static const uint8_t CACHE_SIZE = 4;
80+
ExtendedoneProcessorCache<CACHE_SIZE> zoneProcessorCache;
81+
ExtendedoneManager zoneManager(
82+
zonedbx::kZoneRegistrySize,
83+
zonedbx::kZoneRegistry,
84+
zoneProcessorCache);
85+
```
86+
87+
<a name="UsingZoneManagers"></a>
88+
### Using the Zone Managers
89+
90+
In v1.8, the `ZoneManager` was the parent interface class of all polymorphic
91+
subclasses. So the client code that needed a specific subclass of `ZoneManager`
92+
could do something like this:
93+
94+
```C++
95+
class Controller {
96+
public:
97+
Controller(
98+
ZoneManager* zoneManager,
99+
...
100+
) :
101+
mZoneManager(zoneManager),
102+
...
103+
{}
104+
105+
private:
106+
ZoneManager* mZoneManager;
107+
};
108+
```
109+
110+
Any instance of `BasicZoneManager<SIZE>` or `ExtendedZoneManager<SIZE>` could be
111+
passed into the constructor. This provided some runtime flexibility and code
112+
simplicity. However, the runtime flexibility did not seem useful for the vast
113+
majority of cases and the simplicity offered by the single parent interface
114+
class was paid for by an extra 1100-1300 bytes of flash memory.
115+
116+
In v1.9, the application still has the ability to choose between a
117+
`BasicZoneManager` and an `ExtendedZoneManager` at compile time. The same
118+
`Controller` constructor should look something like this:
119+
120+
```C++
121+
// Define the various TIME_ZONE_TYPE macros in config.h.
122+
#include "config.h"
123+
124+
class Controller {
125+
public:
126+
Controller(
127+
#if TIME_ZONE_TYPE == TIME_ZONE_TYPE_BASIC
128+
BasicZoneManager* zoneManager,
129+
#elif TIME_ZONE_TYPE == TIME_ZONE_TYPE_EXTENDED
130+
ExtendedZoneManager* zoneManager,
131+
#endif
132+
...
133+
) :
134+
mZoneManager(zoneManager),
135+
...
136+
{}
137+
138+
private:
139+
#if TIME_ZONE_TYPE == TIME_ZONE_TYPE_BASIC
140+
BasicZoneManager* mZoneManager;
141+
#elif TIME_ZONE_TYPE == TIME_ZONE_TYPE_EXTENDED
142+
ExtendedZoneManager* mZoneManager;
143+
#endif
144+
};
145+
```
146+
147+
It is assumed that most applications will hard code either the
148+
`BasicZoneManager` or the `ExtendedZoneManager`, and will not need this level
149+
of configuration.
150+
151+
<a name="LinkManagers"></a>
152+
### Link Managers
153+
154+
In v1.8, the `LinkManager` was an interface class with pure virtual methods:
155+
156+
```C++
157+
class LinkManager {
158+
public:
159+
static const uint16_t kInvalidZoneId = 0x0;
160+
virtual uint32_t zoneIdForLinkId(uint32_t linkId) const = 0;
161+
virtual uint16_t linkRegistrySize() const = 0;
162+
};
163+
```
164+
165+
But allowing the `BasicLinkManager` and `ExtendedLinkManager` to be polymorphic
166+
did not seem worth the extra flash usage, similar to the `ZoneManager`
167+
hierarchy.
168+
169+
In v1.9, the pure `virtual` methods were removed, but the static constant
170+
was retained for backwards compatibility:
171+
172+
```C++
173+
class LinkManager {
174+
public:
175+
static const uint16_t kInvalidZoneId = 0x0;
176+
};
177+
```
178+
179+
The `BasicLinkManager` and `ExtendedLinkManager` should be used directly,
180+
instead of through the `LinkManager` interface. Since Link Managers were
181+
introduced only in v1.8, I expect almost no one to be affected by this.
182+
10183
<a name="MigratingToVersion180"></a>
11184
## Migrating to v1.8.0
12185

0 commit comments

Comments
 (0)