diff options
author | 2016-06-14 13:15:26 +0000 | |
---|---|---|
committer | 2016-06-15 08:32:42 +0000 | |
commit | 8fefee65ee7154160d06de255eafaf80e71c424a (patch) | |
tree | ff464168a685908cbafe4e7a184550f0aa30bbea /src/test/java/com/google/devtools/build | |
parent | c5e393b4ba7f5f28b35cae3f55bfeb03ca31cb3e (diff) |
Optimize memory use of AttributeContainer:
- Relatively few locations are set relative to the number of attributes.
Replace the sparse array with a dense one.
- BitSet requires a minimum of two objects (48 bytes in our current JVM),
but we set an average of just six bits. Replace it with a list of
indices packed into a byte[], shared with the locations array.
Also add some assertions to help the next reader.
--
MOS_MIGRATED_REVID=124830576
Diffstat (limited to 'src/test/java/com/google/devtools/build')
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/packages/AttributeContainerTest.java | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/packages/AttributeContainerTest.java b/src/test/java/com/google/devtools/build/lib/packages/AttributeContainerTest.java index 1aa0790cd9..8bf923b589 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/AttributeContainerTest.java +++ b/src/test/java/com/google/devtools/build/lib/packages/AttributeContainerTest.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.packages; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import com.google.devtools.build.lib.events.Location; @@ -27,6 +28,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import java.util.Arrays; +import java.util.Collections; +import java.util.Random; + /** * Unit tests for {@link AttributeContainer}. */ @@ -99,4 +104,53 @@ public class AttributeContainerTest { assertEquals(location2, container.getAttributeLocation(attribute2.getName())); assertNull(container.getAttributeLocation("nomatch")); } + + @Test + public void testPackedState() throws Exception { + Random rng = new Random(); + // The state packing machinery has special behavior at multiples of 8, + // so set enough explicit values and locations to exercise that. + final int N = 17; + Attribute[] attributes = new Attribute[N]; + for (int i = 0; i < N; ++i) { + attributes[i] = ruleClass.getAttribute(i); + } + Object someValue = new Object(); + Location[] locations = new Location[N]; + for (int i = 0; i < N; ++i) { + locations[i] = newLocation(); + } + assertTrue(locations[0] != locations[1]); // test relies on checking reference inequality + for (int explicitCount = 0; explicitCount <= N; ++explicitCount) { + for (int locationCount = 0; locationCount <= N; ++locationCount) { + AttributeContainer container = new AttributeContainer(ruleClass); + // Shuffle the attributes each time through, to exercise + // different stored indices and orderings. + Collections.shuffle(Arrays.asList(attributes)); + // Also randomly interleave calls to the two setters. + int valuePassKey = rng.nextInt(1 << N); + int locationPassKey = rng.nextInt(1 << N); + for (int pass = 0; pass <= 1; ++pass) { + for (int i = 0; i < explicitCount; ++i) { + if (pass == ((valuePassKey >> i) & 1)) { + container.setAttributeValue(attributes[i], someValue, true); + } + } + for (int i = 0; i < locationCount; ++i) { + if (pass == ((locationPassKey >> i) & 1)) { + container.setAttributeLocation(attributes[i], locations[i]); + } + } + } + for (int i = 0; i < N; ++i) { + boolean expected = i < explicitCount; + assertEquals(expected, container.isAttributeValueExplicitlySpecified(attributes[i])); + } + for (int i = 0; i < N; ++i) { + Location expected = i < locationCount ? locations[i] : null; + assertSame(expected, container.getAttributeLocation(attributes[i].getName())); + } + } + } + } } |