Skip to content

Commit

Permalink
Add ability to bisect releasing ComponentHost by mount index and root…
Browse files Browse the repository at this point in the history
… component

Reviewed By: pasqualeanatriello

Differential Revision: D14386863

fbshipit-source-id: fe74b9d0f33b3236b897eb20e1ae3337b25742ee
  • Loading branch information
astreet authored and facebook-github-bot committed Mar 8, 2019
1 parent 66d65fe commit 6d25c57
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2014-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.facebook.litho;

import com.facebook.litho.config.ComponentsConfiguration;

/** A temporary utility to help with bisecting a problem with mount content pooling. See S168698. */
public class ComponentHostRecycleUtil {

static boolean shouldSkipRecyclingComponentHost(int mountIndex, String rootComponentName) {
final boolean isMountIndexBisectEnabled = ComponentsConfiguration.isMountIndexBisectEnabled;
final boolean isRootComponentBisectEnabled =
ComponentsConfiguration.isRootComponentBisectEnabled;
if (!isMountIndexBisectEnabled && !isRootComponentBisectEnabled) {
return false;
}

if (!isRootComponentBisectEnabled) {
return passesMountIndexBisect(mountIndex);
} else if (!isMountIndexBisectEnabled) {
return passesRootComponentBisect(rootComponentName);
} else {
return passesMountIndexBisect(mountIndex) && passesRootComponentBisect(rootComponentName);
}
}

private static boolean passesRootComponentBisect(String rootComponentName) {
final String start = ComponentsConfiguration.rootComponentBisectStart;
final String end = ComponentsConfiguration.rootComponentBisectEnd;

return rootComponentName.compareToIgnoreCase(start) >= 0
&& rootComponentName.compareToIgnoreCase(end) <= 0;
}

private static boolean passesMountIndexBisect(int mountIndex) {
return mountIndex >= ComponentsConfiguration.mountIndexBisectStart
&& mountIndex <= ComponentsConfiguration.mountIndexBisectEnd;
}
}
9 changes: 8 additions & 1 deletion litho-core/src/main/java/com/facebook/litho/MountState.java
Original file line number Diff line number Diff line change
Expand Up @@ -2406,7 +2406,14 @@ private void unmountItem(
mCanMountIncrementallyMountItems.delete(mLayoutOutputsIds[index]);
}

item.releaseMountContent(mContext.getAndroidContext());
final String rootComponentName =
mLastMountedLayoutState == null
? "null_layout"
: mLastMountedLayoutState.mRootComponentName;
if (!(isHostSpec(component)
&& ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(index, rootComponentName))) {
item.releaseMountContent(mContext.getAndroidContext());
}

if (mMountStats.isLoggingEnabled) {
mMountStats.unmountedTimes.add((System.nanoTime() - startTime) / NS_IN_MS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,12 @@ public static boolean isRenderInfoDebuggingEnabled() {

// todo T40814333 clean up after running experiment.
public static boolean splitLayoutForMeasureAndRangeEstimation = false;

public static boolean isMountIndexBisectEnabled = false;
public static int mountIndexBisectStart = 0;
public static int mountIndexBisectEnd = 1000;

public static boolean isRootComponentBisectEnabled = false;
public static String rootComponentBisectStart = "aaaaa";
public static String rootComponentBisectEnd = "zzzzz";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* Copyright 2014-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.facebook.litho;

import static org.assertj.core.api.Java6Assertions.assertThat;

import com.facebook.litho.config.ComponentsConfiguration;
import com.facebook.litho.testing.testrunner.ComponentsTestRunner;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(ComponentsTestRunner.class)
public class ComponentHostRecycleUtilTest {

@After
public void tearDown() {
ComponentsConfiguration.isMountIndexBisectEnabled = false;
ComponentsConfiguration.mountIndexBisectStart = 0;
ComponentsConfiguration.mountIndexBisectEnd = 100;

ComponentsConfiguration.isRootComponentBisectEnabled = false;
ComponentsConfiguration.rootComponentBisectStart = "aaaaa";
ComponentsConfiguration.rootComponentBisectEnd = "zzzzz";
}

@Test
public void testBothDisabled() {
ComponentsConfiguration.isMountIndexBisectEnabled = false;
ComponentsConfiguration.isRootComponentBisectEnabled = false;

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isFalse();
}

@Test
public void testMountIndexBisect() {
ComponentsConfiguration.isMountIndexBisectEnabled = true;
ComponentsConfiguration.mountIndexBisectStart = 0;
ComponentsConfiguration.mountIndexBisectEnd = 100;

ComponentsConfiguration.isRootComponentBisectEnabled = false;
ComponentsConfiguration.rootComponentBisectStart = "bar";
ComponentsConfiguration.rootComponentBisectEnd = "bar";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isTrue();

ComponentsConfiguration.mountIndexBisectStart = 5;
ComponentsConfiguration.mountIndexBisectEnd = 10;

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(4, "foo")).isFalse();

ComponentsConfiguration.mountIndexBisectStart = 4;
ComponentsConfiguration.mountIndexBisectEnd = 4;

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(4, "foo")).isTrue();
}

@Test
public void testRootComponentBisect() {
ComponentsConfiguration.isMountIndexBisectEnabled = false;
ComponentsConfiguration.mountIndexBisectStart = 4;
ComponentsConfiguration.mountIndexBisectEnd = 4;

ComponentsConfiguration.isRootComponentBisectEnabled = true;
ComponentsConfiguration.rootComponentBisectStart = "aaaaa";
ComponentsConfiguration.rootComponentBisectEnd = "zzzzz";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isTrue();

ComponentsConfiguration.rootComponentBisectStart = "foo";
ComponentsConfiguration.rootComponentBisectEnd = "foo";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isTrue();

ComponentsConfiguration.rootComponentBisectStart = "bar";
ComponentsConfiguration.rootComponentBisectEnd = "bar";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isFalse();

ComponentsConfiguration.rootComponentBisectStart = "FOO";
ComponentsConfiguration.rootComponentBisectEnd = "FOO";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isTrue();

ComponentsConfiguration.rootComponentBisectStart = "foo";
ComponentsConfiguration.rootComponentBisectEnd = "goo";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isTrue();

ComponentsConfiguration.rootComponentBisectStart = "bar";
ComponentsConfiguration.rootComponentBisectEnd = "foo";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isTrue();

ComponentsConfiguration.rootComponentBisectStart = "bar";
ComponentsConfiguration.rootComponentBisectEnd = "baz";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isFalse();
}

@Test
public void testBoth() {
ComponentsConfiguration.isMountIndexBisectEnabled = true;
ComponentsConfiguration.mountIndexBisectStart = 0;
ComponentsConfiguration.mountIndexBisectEnd = 100;

ComponentsConfiguration.isRootComponentBisectEnabled = true;
ComponentsConfiguration.rootComponentBisectStart = "aaaaa";
ComponentsConfiguration.rootComponentBisectEnd = "zzzzz";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isTrue();

ComponentsConfiguration.mountIndexBisectStart = 4;
ComponentsConfiguration.mountIndexBisectEnd = 4;

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isFalse();
assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(4, "foo")).isTrue();

ComponentsConfiguration.rootComponentBisectStart = "foo";
ComponentsConfiguration.rootComponentBisectEnd = "foo";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(0, "foo")).isFalse();
assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(4, "foo")).isTrue();

ComponentsConfiguration.rootComponentBisectStart = "bar";
ComponentsConfiguration.rootComponentBisectEnd = "bar";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(4, "foo")).isFalse();

ComponentsConfiguration.rootComponentBisectStart = "FOO";
ComponentsConfiguration.rootComponentBisectEnd = "FOO";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(4, "foo")).isTrue();

ComponentsConfiguration.mountIndexBisectStart = 3;
ComponentsConfiguration.mountIndexBisectEnd = 5;
ComponentsConfiguration.rootComponentBisectStart = "foo";
ComponentsConfiguration.rootComponentBisectEnd = "goo";

assertThat(ComponentHostRecycleUtil.shouldSkipRecyclingComponentHost(4, "foo")).isTrue();
}
}

0 comments on commit 6d25c57

Please sign in to comment.