Skip to content

Commit

Permalink
ICU-22991 Reduce fStamp to 8 bits
Browse files Browse the repository at this point in the history
Reduce 24x3=72 bytes per Calendar object by changing
from 32 bits integer to 8 bits integer for the stamp array.
Reset the fNextStamp inside the clear function.

fix
  • Loading branch information
FrankYFTang committed Dec 31, 2024
1 parent d9d09db commit b31ce36
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 25 deletions.
26 changes: 11 additions & 15 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,7 +700,7 @@ fIsTimeSet(false),
fAreFieldsSet(false),
fAreAllFieldsSet(false),
fAreFieldsVirtuallySet(false),
fNextStamp(static_cast<int32_t>(kMinimumUserStamp)),
fNextStamp(kMinimumUserStamp),
fTime(0),
fLenient(true),
fZone(nullptr),
Expand Down Expand Up @@ -728,7 +728,7 @@ fIsTimeSet(false),
fAreFieldsSet(false),
fAreAllFieldsSet(false),
fAreFieldsVirtuallySet(false),
fNextStamp(static_cast<int32_t>(kMinimumUserStamp)),
fNextStamp(kMinimumUserStamp),
fTime(0),
fLenient(true),
fZone(nullptr),
Expand Down Expand Up @@ -763,7 +763,7 @@ fIsTimeSet(false),
fAreFieldsSet(false),
fAreAllFieldsSet(false),
fAreFieldsVirtuallySet(false),
fNextStamp(static_cast<int32_t>(kMinimumUserStamp)),
fNextStamp(kMinimumUserStamp),
fTime(0),
fLenient(true),
fZone(nullptr),
Expand Down Expand Up @@ -1166,12 +1166,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 @@ -1206,7 +1203,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 @@ -1267,10 +1264,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
6 changes: 3 additions & 3 deletions icu4c/source/i18n/unicode/calendar.h
Original file line number Diff line number Diff line change
Expand Up @@ -1951,9 +1951,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 127 are legal user set values.
*/
int32_t fStamp[UCAL_FIELD_COUNT];
int8_t fStamp[UCAL_FIELD_COUNT];

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

/**
* Recalculates the time stamp array (fStamp).
Expand Down
16 changes: 9 additions & 7 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 @@ -1355,9 +1355,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 Byte.MAX_VALUE 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 +1507,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 +1684,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 +1721,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 @@ -2057,6 +2057,7 @@ public void setTimeInMillis( long millis ) {
for (int i=0; i<fields.length; ++i) {
fields[i] = stamp[i] = 0; // UNSET == 0
}
nextStamp = MINIMUM_USER_STAMP;

}

Expand Down Expand Up @@ -2458,6 +2459,7 @@ public final void clear()
for (int i=0; i<fields.length; ++i) {
fields[i] = stamp[i] = 0; // UNSET == 0
}
nextStamp = MINIMUM_USER_STAMP;
isTimeSet = areFieldsSet = areAllFieldsSet = areFieldsVirtuallySet = false;
}

Expand Down Expand Up @@ -4904,7 +4906,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 b31ce36

Please sign in to comment.