Skip to content

Commit

Permalink
ICU-22991 Reduce fStamp to 8 bits
Browse files Browse the repository at this point in the history
See #3323
  • Loading branch information
FrankYFTang committed Jan 7, 2025
1 parent 4c3622f commit 6091406
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 83 deletions.
32 changes: 9 additions & 23 deletions icu4c/source/i18n/calendar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ U_CFUNC void ucal_dump(UCalendar* cal) {
#endif

/* Max value for stamp allowable before recalculation */
#define STAMP_MAX 10000
#define STAMP_MAX 127

static const char * const gCalTypes[] = {
"gregorian",
Expand Down Expand Up @@ -700,10 +700,7 @@ fIsTimeSet(false),
fAreFieldsSet(false),
fAreAllFieldsSet(false),
fAreFieldsVirtuallySet(false),
fNextStamp(static_cast<int32_t>(kMinimumUserStamp)),
fTime(0),
fLenient(true),
fZone(nullptr),
fRepeatedWallTime(UCAL_WALLTIME_LAST),
fSkippedWallTime(UCAL_WALLTIME_LAST)
{
Expand All @@ -726,10 +723,7 @@ fIsTimeSet(false),
fAreFieldsSet(false),
fAreAllFieldsSet(false),
fAreFieldsVirtuallySet(false),
fNextStamp(static_cast<int32_t>(kMinimumUserStamp)),
fTime(0),
fLenient(true),
fZone(nullptr),
fRepeatedWallTime(UCAL_WALLTIME_LAST),
fSkippedWallTime(UCAL_WALLTIME_LAST)
{
Expand Down Expand Up @@ -759,10 +753,7 @@ fIsTimeSet(false),
fAreFieldsSet(false),
fAreAllFieldsSet(false),
fAreFieldsVirtuallySet(false),
fNextStamp(static_cast<int32_t>(kMinimumUserStamp)),
fTime(0),
fLenient(true),
fZone(nullptr),
fRepeatedWallTime(UCAL_WALLTIME_LAST),
fSkippedWallTime(UCAL_WALLTIME_LAST)
{
Expand Down Expand Up @@ -792,7 +783,6 @@ Calendar::~Calendar()
Calendar::Calendar(const Calendar &source)
: UObject(source)
{
fZone = nullptr;
*this = source;
}

Expand Down Expand Up @@ -1163,12 +1153,9 @@ Calendar::setTimeInMillis( double millis, UErrorCode& status ) {
fAreFieldsSet = fAreAllFieldsSet = false;
fIsTimeSet = fAreFieldsVirtuallySet = true;

for (int32_t i=0; i<UCAL_FIELD_COUNT; ++i) {
fFields[i] = 0;
fStamp[i] = kUnset;
}


uprv_memset(fFields, 0, sizeof(fFields));
uprv_memset(fStamp, kUnset, sizeof(fStamp));
fNextStamp = kMinimumUserStamp;
}

// -------------------------------------
Expand Down Expand Up @@ -1203,7 +1190,7 @@ Calendar::set(UCalendarDateFields field, int32_t value)
computeFields(ec);
}
fFields[field] = value;
/* Ensure that the fNextStamp value doesn't go pass max value for int32_t */
/* Ensure that the fNextStamp value doesn't go pass max value for int8_t */
if (fNextStamp == STAMP_MAX) {
recalculateStamp();
}
Expand Down Expand Up @@ -1264,10 +1251,9 @@ void Calendar::setRelatedYear(int32_t year)
void
Calendar::clear()
{
for (int32_t i=0; i<UCAL_FIELD_COUNT; ++i) {
fFields[i] = 0; // Must do this; other code depends on it
fStamp[i] = kUnset;
}
uprv_memset(fFields, 0, sizeof(fFields));
uprv_memset(fStamp, kUnset, sizeof(fStamp));
fNextStamp = kMinimumUserStamp;
fIsTimeSet = fAreFieldsSet = fAreAllFieldsSet = fAreFieldsVirtuallySet = false;
// fTime is not 'cleared' - may be used if no fields are set.
}
Expand Down Expand Up @@ -4228,7 +4214,7 @@ Calendar::recalculateStamp() {
int32_t currentValue;
int32_t j, i;

fNextStamp = 1;
fNextStamp = kInternallySet;

for (j = 0; j < UCAL_FIELD_COUNT; j++) {
currentValue = STAMP_MAX;
Expand Down
95 changes: 48 additions & 47 deletions icu4c/source/i18n/unicode/calendar.h
Original file line number Diff line number Diff line change
Expand Up @@ -1882,38 +1882,6 @@ class U_I18N_API Calendar : public UObject {
*/
int32_t getActualHelper(UCalendarDateFields field, int32_t startValue, int32_t endValue, UErrorCode &status) const;


private:
/**
* The flag which indicates if the current time is set in the calendar.
*/
UBool fIsTimeSet;

/**
* True if the fields are in sync with the currently set time of this Calendar.
* If false, then the next attempt to get the value of a field will
* force a recomputation of all fields from the current value of the time
* field.
* <P>
* This should really be named areFieldsInSync, but the old name is retained
* for backward compatibility.
*/
UBool fAreFieldsSet;

/**
* True if all of the fields have been set. This is initially false, and set to
* true by computeFields().
*/
UBool fAreAllFieldsSet;

/**
* True if all fields have been virtually set, but have not yet been
* computed. This occurs only in setTimeInMillis(). A calendar set
* to this state will compute all fields from the time if it becomes
* necessary, but otherwise will delay such computation.
*/
UBool fAreFieldsVirtuallySet;

protected:
/**
* Get the current time without recomputing.
Expand Down Expand Up @@ -1952,9 +1920,9 @@ class U_I18N_API Calendar : public UObject {
/**
* Pseudo-time-stamps which specify when each field was set. There
* are two special values, UNSET and INTERNALLY_SET. Values from
* MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
* MINIMUM_USER_SET to STAMP_MAX are legal user set values.
*/
int32_t fStamp[UCAL_FIELD_COUNT];
int8_t fStamp[UCAL_FIELD_COUNT];

protected:
/**
Expand Down Expand Up @@ -2170,7 +2138,7 @@ class U_I18N_API Calendar : public UObject {
/**
* The next available value for fStamp[]
*/
int32_t fNextStamp;// = MINIMUM_USER_STAMP;
int8_t fNextStamp = kMinimumUserStamp;

/**
* Recalculates the time stamp array (fStamp).
Expand All @@ -2181,30 +2149,60 @@ class U_I18N_API Calendar : public UObject {
/**
* The current time set for the calendar.
*/
UDate fTime;
UDate fTime = 0;

/**
* @see #setLenient
* Time zone affects the time calculation done by Calendar. Calendar subclasses use
* the time zone data to produce the local time. Always set; never nullptr.
*/
UBool fLenient;
TimeZone* fZone = nullptr;

/**
* Time zone affects the time calculation done by Calendar. Calendar subclasses use
* the time zone data to produce the local time. Always set; never nullptr.
* The flag which indicates if the current time is set in the calendar.
*/
bool fIsTimeSet:1;

/**
* True if the fields are in sync with the currently set time of this Calendar.
* If false, then the next attempt to get the value of a field will
* force a recomputation of all fields from the current value of the time
* field.
* <P>
* This should really be named areFieldsInSync, but the old name is retained
* for backward compatibility.
*/
bool fAreFieldsSet:1;

/**
* True if all of the fields have been set. This is initially false, and set to
* true by computeFields().
*/
bool fAreAllFieldsSet:1;

/**
* True if all fields have been virtually set, but have not yet been
* computed. This occurs only in setTimeInMillis(). A calendar set
* to this state will compute all fields from the time if it becomes
* necessary, but otherwise will delay such computation.
*/
bool fAreFieldsVirtuallySet:1;

/**
* @see #setLenient
*/
TimeZone* fZone;
bool fLenient:1;

/**
* Option for repeated wall time
* @see #setRepeatedWallTimeOption
*/
UCalendarWallTimeOption fRepeatedWallTime;
UCalendarWallTimeOption fRepeatedWallTime:3; // Somehow MSVC need 3 bits for UCalendarWallTimeOption

/**
* Option for skipped wall time
* @see #setSkippedWallTimeOption
*/
UCalendarWallTimeOption fSkippedWallTime;
UCalendarWallTimeOption fSkippedWallTime:3; // Somehow MSVC need 3 bits for UCalendarWallTimeOption

/**
* Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent. They are
Expand All @@ -2214,11 +2212,14 @@ class U_I18N_API Calendar : public UObject {
* out the week count for a specific date for a given locale. These must be set when
* a Calendar is constructed.
*/
UCalendarDaysOfWeek fFirstDayOfWeek;
uint8_t fMinimalDaysInFirstWeek;
UCalendarDaysOfWeek fWeekendOnset;
UCalendarDaysOfWeek fFirstDayOfWeek:4; // Somehow MSVC need 4 bits for
// UCalendarDaysOfWeek
UCalendarDaysOfWeek fWeekendOnset:4; // Somehow MSVC need 4 bits for
// UCalendarDaysOfWeek
UCalendarDaysOfWeek fWeekendCease:4; // Somehow MSVC need 4 bits for
// UCalendarDaysOfWeek
uint8_t fMinimalDaysInFirstWeek;
int32_t fWeekendOnsetMillis;
UCalendarDaysOfWeek fWeekendCease;
int32_t fWeekendCeaseMillis;

/**
Expand Down
27 changes: 14 additions & 13 deletions icu4j/main/core/src/main/java/com/ibm/icu/util/Calendar.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.io.Serializable;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
import java.util.MissingResourceException;
Expand Down Expand Up @@ -1355,9 +1356,9 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
/**
* Pseudo-time-stamps which specify when each field was set. There
* are two special values, UNSET and INTERNALLY_SET. Values from
* MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
* MINIMUM_USER_SET to STAMP_MAX are legal user set values.
*/
private transient int stamp[];
private transient byte stamp[];

/**
* The currently set time for this calendar, expressed in milliseconds after
Expand Down Expand Up @@ -1507,10 +1508,10 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
* The next available value for <code>stamp[]</code>, an internal array.
* @serial
*/
private transient int nextStamp = MINIMUM_USER_STAMP;
private transient byte nextStamp = MINIMUM_USER_STAMP;

/* Max value for stamp allowable before recalculation */
private static int STAMP_MAX = 10000;
private static byte STAMP_MAX = Byte.MAX_VALUE;

// the internal serial version which says which version was written
// - 0 (default) for version up to JDK 1.1.5
Expand Down Expand Up @@ -1684,7 +1685,7 @@ private void setCalendarLocale(ULocale locale) {

private void recalculateStamp() {
int index;
int currentValue;
byte currentValue;
int j, i;

nextStamp = 1;
Expand Down Expand Up @@ -1721,7 +1722,7 @@ private void initInternal()
throw new IllegalStateException("Invalid fields[]");
}
///CLOVER:ON
stamp = new int[fields.length];
stamp = new byte[fields.length];
int mask = (1 << ERA) |
(1 << YEAR) |
(1 << MONTH) |
Expand Down Expand Up @@ -2054,9 +2055,9 @@ public void setTimeInMillis( long millis ) {
areFieldsSet = areAllFieldsSet = false;
isTimeSet = areFieldsVirtuallySet = true;

for (int i=0; i<fields.length; ++i) {
fields[i] = stamp[i] = 0; // UNSET == 0
}
Arrays.fill(fields, 0);
Arrays.fill(stamp, (byte)0);
nextStamp = MINIMUM_USER_STAMP;

}

Expand Down Expand Up @@ -2455,9 +2456,9 @@ public final void setRelatedYear(int year) {
*/
public final void clear()
{
for (int i=0; i<fields.length; ++i) {
fields[i] = stamp[i] = 0; // UNSET == 0
}
Arrays.fill(fields, 0);
Arrays.fill(stamp, (byte)0);
nextStamp = MINIMUM_USER_STAMP;
isTimeSet = areFieldsSet = areAllFieldsSet = areFieldsVirtuallySet = false;
}

Expand Down Expand Up @@ -4904,7 +4905,7 @@ public Object clone()
Calendar other = (Calendar) super.clone();

other.fields = new int[fields.length];
other.stamp = new int[fields.length];
other.stamp = new byte[fields.length];
System.arraycopy(this.fields, 0, other.fields, 0, fields.length);
System.arraycopy(this.stamp, 0, other.stamp, 0, fields.length);

Expand Down

0 comments on commit 6091406

Please sign in to comment.