Skip to content

Commit

Permalink
Remove field SmallSortedMap.maxArraySize
Browse files Browse the repository at this point in the history
It's always set to 16 in production code.

Except for when it's set to 0 for the immutable empty SmallSortedMap, but the number doesn't change anything for that immutable empty map (it's always empty, it will never hit the max).

This should save 4 bytes of memory per SmallSortedMap.

PiperOrigin-RevId: 636035193
  • Loading branch information
mhansen authored and copybara-github committed May 22, 2024
1 parent c05be32 commit 16e0a63
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 99 deletions.
10 changes: 4 additions & 6 deletions java/core/src/main/java/com/google/protobuf/FieldSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,19 @@ public interface FieldDescriptorLite<T extends FieldDescriptorLite<T>> extends C
MessageLite.Builder internalMergeFrom(MessageLite.Builder to, MessageLite from);
}

private static final int DEFAULT_FIELD_MAP_ARRAY_SIZE = 16;

private final SmallSortedMap<T, Object> fields;
private boolean isImmutable;
private boolean hasLazyField;

/** Construct a new FieldSet. */
private FieldSet() {
this.fields = SmallSortedMap.newFieldMap(DEFAULT_FIELD_MAP_ARRAY_SIZE);
this.fields = SmallSortedMap.newFieldMap();
}

/** Construct an empty FieldSet. This is only used to initialize DEFAULT_INSTANCE. */
@SuppressWarnings("unused")
private FieldSet(final boolean dummy) {
this(SmallSortedMap.<T>newFieldMap(0));
this(SmallSortedMap.<T>newFieldMap());
makeImmutable();
}

Expand Down Expand Up @@ -185,7 +183,7 @@ public Map<T, Object> getAllFields() {

private static <T extends FieldDescriptorLite<T>> SmallSortedMap<T, Object> cloneAllFieldsMap(
SmallSortedMap<T, Object> fields, boolean copyList, boolean resolveLazyFields) {
SmallSortedMap<T, Object> result = SmallSortedMap.newFieldMap(DEFAULT_FIELD_MAP_ARRAY_SIZE);
SmallSortedMap<T, Object> result = SmallSortedMap.newFieldMap();
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
cloneFieldEntry(result, fields.getArrayEntryAt(i), copyList, resolveLazyFields);
}
Expand Down Expand Up @@ -931,7 +929,7 @@ static final class Builder<T extends FieldDescriptorLite<T>> {
private boolean hasNestedBuilders;

private Builder() {
this(SmallSortedMap.<T>newFieldMap(DEFAULT_FIELD_MAP_ARRAY_SIZE));
this(SmallSortedMap.<T>newFieldMap());
}

private Builder(SmallSortedMap<T, Object> fields) {
Expand Down
33 changes: 14 additions & 19 deletions java/core/src/main/java/com/google/protobuf/SmallSortedMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
// a subclass to aid testability of the core logic.
class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {

static final int DEFAULT_FIELD_MAP_ARRAY_SIZE = 16;

/**
* Creates a new instance for mapping FieldDescriptors to their values. The {@link
* #makeImmutable()} implementation will convert the List values of any repeated fields to
Expand All @@ -67,22 +69,22 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
* mappings.
*/
static <FieldDescriptorType extends FieldSet.FieldDescriptorLite<FieldDescriptorType>>
SmallSortedMap<FieldDescriptorType, Object> newFieldMap(int arraySize) {
return new SmallSortedMap<FieldDescriptorType, Object>(arraySize) {
SmallSortedMap<FieldDescriptorType, Object> newFieldMap() {
return new SmallSortedMap<FieldDescriptorType, Object>() {
@Override
@SuppressWarnings("unchecked")
public void makeImmutable() {
if (!isImmutable()) {
for (int i = 0; i < getNumArrayEntries(); i++) {
final Map.Entry<FieldDescriptorType, Object> entry = getArrayEntryAt(i);
if (entry.getKey().isRepeated()) {
final List value = (List) entry.getValue();
final List<?> value = (List) entry.getValue();
entry.setValue(Collections.unmodifiableList(value));
}
}
for (Map.Entry<FieldDescriptorType, Object> entry : getOverflowEntries()) {
if (entry.getKey().isRepeated()) {
final List value = (List) entry.getValue();
final List<?> value = (List) entry.getValue();
entry.setValue(Collections.unmodifiableList(value));
}
}
Expand All @@ -92,17 +94,11 @@ public void makeImmutable() {
};
}

/**
* Creates a new instance for testing.
*
* @param arraySize The size of the entry array containing the lexicographically smallest
* mappings.
*/
static <K extends Comparable<K>, V> SmallSortedMap<K, V> newInstanceForTest(int arraySize) {
return new SmallSortedMap<K, V>(arraySize);
/** Creates a new instance for testing. */
static <K extends Comparable<K>, V> SmallSortedMap<K, V> newInstanceForTest() {
return new SmallSortedMap<>();
}

private final int maxArraySize;
// The "entry array" is actually a List because generic arrays are not
// allowed. ArrayList also nicely handles the entry shifting on inserts and
// removes.
Expand All @@ -119,8 +115,7 @@ static <K extends Comparable<K>, V> SmallSortedMap<K, V> newInstanceForTest(int
* @code arraySize Size of the array in which the lexicographically smallest mappings are stored.
* (i.e. the {@code k} referred to in the class documentation).
*/
private SmallSortedMap(int arraySize) {
this.maxArraySize = arraySize;
private SmallSortedMap() {
this.entryList = Collections.emptyList();
this.overflowEntries = Collections.emptyMap();
this.overflowEntriesDescending = Collections.emptyMap();
Expand Down Expand Up @@ -215,14 +210,14 @@ public V put(K key, V value) {
}
ensureEntryArrayMutable();
final int insertionPoint = -(index + 1);
if (insertionPoint >= maxArraySize) {
if (insertionPoint >= DEFAULT_FIELD_MAP_ARRAY_SIZE) {
// Put directly in overflow.
return getOverflowEntriesMutable().put(key, value);
}
// Insert new Entry in array.
if (entryList.size() == maxArraySize) {
if (entryList.size() == DEFAULT_FIELD_MAP_ARRAY_SIZE) {
// Shift the last array entry into overflow.
final Entry lastEntryInArray = entryList.remove(maxArraySize - 1);
final Entry lastEntryInArray = entryList.remove(DEFAULT_FIELD_MAP_ARRAY_SIZE - 1);
getOverflowEntriesMutable().put(lastEntryInArray.getKey(), lastEntryInArray.getValue());
}
entryList.add(insertionPoint, new Entry(key, value));
Expand Down Expand Up @@ -357,7 +352,7 @@ private SortedMap<K, V> getOverflowEntriesMutable() {
private void ensureEntryArrayMutable() {
checkMutable();
if (entryList.isEmpty() && !(entryList instanceof ArrayList)) {
entryList = new ArrayList<Entry>(maxArraySize);
entryList = new ArrayList<>(DEFAULT_FIELD_MAP_ARRAY_SIZE);
}
}

Expand Down
Loading

0 comments on commit 16e0a63

Please sign in to comment.