Merge "Adjust concurrency limits based on device."
This commit is contained in:
committed by
Android (Google) Code Review
commit
dd6fb91d69
@@ -17,6 +17,7 @@
|
||||
package com.android.server.job;
|
||||
|
||||
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||
import static android.util.DataUnit.GIGABYTES;
|
||||
|
||||
import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
|
||||
@@ -58,6 +59,7 @@ import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.app.IBatteryStats;
|
||||
import com.android.internal.app.procstats.ProcessStats;
|
||||
import com.android.internal.util.MemInfoReader;
|
||||
import com.android.internal.util.StatLogger;
|
||||
import com.android.server.JobSchedulerBackgroundThread;
|
||||
import com.android.server.LocalServices;
|
||||
@@ -85,11 +87,33 @@ class JobConcurrencyManager {
|
||||
private static final boolean DEBUG = JobSchedulerService.DEBUG;
|
||||
|
||||
/** The maximum number of concurrent jobs we'll aim to run at one time. */
|
||||
public static final int STANDARD_CONCURRENCY_LIMIT = 16;
|
||||
@VisibleForTesting
|
||||
static final int MAX_CONCURRENCY_LIMIT = 64;
|
||||
/** The maximum number of objects we should retain in memory when not in use. */
|
||||
private static final int MAX_RETAINED_OBJECTS = (int) (1.5 * STANDARD_CONCURRENCY_LIMIT);
|
||||
private static final int MAX_RETAINED_OBJECTS = (int) (1.5 * MAX_CONCURRENCY_LIMIT);
|
||||
|
||||
static final String CONFIG_KEY_PREFIX_CONCURRENCY = "concurrency_";
|
||||
private static final String KEY_CONCURRENCY_LIMIT = CONFIG_KEY_PREFIX_CONCURRENCY + "limit";
|
||||
@VisibleForTesting
|
||||
static final int DEFAULT_CONCURRENCY_LIMIT;
|
||||
|
||||
static {
|
||||
if (ActivityManager.isLowRamDeviceStatic()) {
|
||||
DEFAULT_CONCURRENCY_LIMIT = 8;
|
||||
} else {
|
||||
final long ramBytes = new MemInfoReader().getTotalSize();
|
||||
if (ramBytes <= GIGABYTES.toBytes(6)) {
|
||||
DEFAULT_CONCURRENCY_LIMIT = 16;
|
||||
} else if (ramBytes <= GIGABYTES.toBytes(8)) {
|
||||
DEFAULT_CONCURRENCY_LIMIT = 20;
|
||||
} else if (ramBytes <= GIGABYTES.toBytes(12)) {
|
||||
DEFAULT_CONCURRENCY_LIMIT = 32;
|
||||
} else {
|
||||
DEFAULT_CONCURRENCY_LIMIT = 40;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final String KEY_SCREEN_OFF_ADJUSTMENT_DELAY_MS =
|
||||
CONFIG_KEY_PREFIX_CONCURRENCY + "screen_off_adjustment_delay_ms";
|
||||
private static final long DEFAULT_SCREEN_OFF_ADJUSTMENT_DELAY_MS = 30_000;
|
||||
@@ -100,7 +124,7 @@ class JobConcurrencyManager {
|
||||
@VisibleForTesting
|
||||
static final String KEY_PKG_CONCURRENCY_LIMIT_REGULAR =
|
||||
CONFIG_KEY_PREFIX_CONCURRENCY + "pkg_concurrency_limit_regular";
|
||||
private static final int DEFAULT_PKG_CONCURRENCY_LIMIT_REGULAR = STANDARD_CONCURRENCY_LIMIT / 2;
|
||||
private static final int DEFAULT_PKG_CONCURRENCY_LIMIT_REGULAR = DEFAULT_CONCURRENCY_LIMIT / 2;
|
||||
@VisibleForTesting
|
||||
static final String KEY_ENABLE_MAX_WAIT_TIME_BYPASS =
|
||||
CONFIG_KEY_PREFIX_CONCURRENCY + "enable_max_wait_time_bypass";
|
||||
@@ -209,84 +233,100 @@ class JobConcurrencyManager {
|
||||
|
||||
private static final WorkConfigLimitsPerMemoryTrimLevel CONFIG_LIMITS_SCREEN_ON =
|
||||
new WorkConfigLimitsPerMemoryTrimLevel(
|
||||
new WorkTypeConfig("screen_on_normal", 11,
|
||||
new WorkTypeConfig("screen_on_normal", DEFAULT_CONCURRENCY_LIMIT,
|
||||
/* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 3 / 4,
|
||||
// defaultMin
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
|
||||
Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 2),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1)),
|
||||
List.of(Pair.create(WORK_TYPE_TOP, .4f),
|
||||
Pair.create(WORK_TYPE_FGS, .2f),
|
||||
Pair.create(WORK_TYPE_EJ, .2f), Pair.create(WORK_TYPE_BG, .1f),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f)),
|
||||
// defaultMax
|
||||
List.of(Pair.create(WORK_TYPE_BG, 6),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 2),
|
||||
Pair.create(WORK_TYPE_BGUSER, 3))
|
||||
List.of(Pair.create(WORK_TYPE_BG, .5f),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .25f),
|
||||
Pair.create(WORK_TYPE_BGUSER, .2f))
|
||||
),
|
||||
new WorkTypeConfig("screen_on_moderate", 9,
|
||||
new WorkTypeConfig("screen_on_moderate", DEFAULT_CONCURRENCY_LIMIT,
|
||||
/* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT / 2,
|
||||
// defaultMin
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
|
||||
Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 1),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1)),
|
||||
List.of(Pair.create(WORK_TYPE_TOP, .4f),
|
||||
Pair.create(WORK_TYPE_FGS, .1f),
|
||||
Pair.create(WORK_TYPE_EJ, .1f), Pair.create(WORK_TYPE_BG, .1f),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f)),
|
||||
// defaultMax
|
||||
List.of(Pair.create(WORK_TYPE_BG, 4),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1))
|
||||
List.of(Pair.create(WORK_TYPE_BG, .4f),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f),
|
||||
Pair.create(WORK_TYPE_BGUSER, .1f))
|
||||
),
|
||||
new WorkTypeConfig("screen_on_low", 6,
|
||||
new WorkTypeConfig("screen_on_low", DEFAULT_CONCURRENCY_LIMIT,
|
||||
/* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 4 / 10,
|
||||
// defaultMin
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
|
||||
Pair.create(WORK_TYPE_EJ, 1)),
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_FGS, .1f),
|
||||
Pair.create(WORK_TYPE_EJ, .1f)),
|
||||
// defaultMax
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1))
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1.0f / 6),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 6))
|
||||
),
|
||||
new WorkTypeConfig("screen_on_critical", 6,
|
||||
new WorkTypeConfig("screen_on_critical", DEFAULT_CONCURRENCY_LIMIT,
|
||||
/* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 4 / 10,
|
||||
// defaultMin
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
|
||||
Pair.create(WORK_TYPE_EJ, 1)),
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_FGS, .1f),
|
||||
Pair.create(WORK_TYPE_EJ, .1f)),
|
||||
// defaultMax
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1))
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / 6),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1.0f / 6),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 6))
|
||||
)
|
||||
);
|
||||
private static final WorkConfigLimitsPerMemoryTrimLevel CONFIG_LIMITS_SCREEN_OFF =
|
||||
new WorkConfigLimitsPerMemoryTrimLevel(
|
||||
new WorkTypeConfig("screen_off_normal", 16,
|
||||
new WorkTypeConfig("screen_off_normal", DEFAULT_CONCURRENCY_LIMIT,
|
||||
/* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT,
|
||||
// defaultMin
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 2),
|
||||
Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 2),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1)),
|
||||
List.of(Pair.create(WORK_TYPE_TOP, .3f),
|
||||
Pair.create(WORK_TYPE_FGS, .2f),
|
||||
Pair.create(WORK_TYPE_EJ, .3f), Pair.create(WORK_TYPE_BG, .2f),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f)),
|
||||
// defaultMax
|
||||
List.of(Pair.create(WORK_TYPE_BG, 10),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 2),
|
||||
Pair.create(WORK_TYPE_BGUSER, 3))
|
||||
List.of(Pair.create(WORK_TYPE_BG, .6f),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .2f),
|
||||
Pair.create(WORK_TYPE_BGUSER, .2f))
|
||||
),
|
||||
new WorkTypeConfig("screen_off_moderate", 14,
|
||||
new WorkTypeConfig("screen_off_moderate", DEFAULT_CONCURRENCY_LIMIT,
|
||||
/* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 9 / 10,
|
||||
// defaultMin
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 2),
|
||||
Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 2),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1)),
|
||||
List.of(Pair.create(WORK_TYPE_TOP, .3f),
|
||||
Pair.create(WORK_TYPE_FGS, .2f),
|
||||
Pair.create(WORK_TYPE_EJ, .3f), Pair.create(WORK_TYPE_BG, .2f),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f)),
|
||||
// defaultMax
|
||||
List.of(Pair.create(WORK_TYPE_BG, 7),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1))
|
||||
List.of(Pair.create(WORK_TYPE_BG, .5f),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f),
|
||||
Pair.create(WORK_TYPE_BGUSER, .1f))
|
||||
),
|
||||
new WorkTypeConfig("screen_off_low", 9,
|
||||
new WorkTypeConfig("screen_off_low", DEFAULT_CONCURRENCY_LIMIT,
|
||||
/* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 6 / 10,
|
||||
// defaultMin
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
|
||||
Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 1)),
|
||||
List.of(Pair.create(WORK_TYPE_TOP, .4f),
|
||||
Pair.create(WORK_TYPE_FGS, .1f),
|
||||
Pair.create(WORK_TYPE_EJ, .2f), Pair.create(WORK_TYPE_BG, .1f)),
|
||||
// defaultMax
|
||||
List.of(Pair.create(WORK_TYPE_BG, 3),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1))
|
||||
List.of(Pair.create(WORK_TYPE_BG, .25f),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f),
|
||||
Pair.create(WORK_TYPE_BGUSER, .1f))
|
||||
),
|
||||
new WorkTypeConfig("screen_off_critical", 6,
|
||||
new WorkTypeConfig("screen_off_critical", DEFAULT_CONCURRENCY_LIMIT,
|
||||
/* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 4 / 10,
|
||||
// defaultMin
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
|
||||
Pair.create(WORK_TYPE_EJ, 1)),
|
||||
List.of(Pair.create(WORK_TYPE_TOP, .5f),
|
||||
Pair.create(WORK_TYPE_FGS, .1f),
|
||||
Pair.create(WORK_TYPE_EJ, .1f)),
|
||||
// defaultMax
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1))
|
||||
List.of(Pair.create(WORK_TYPE_BG, .1f),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f),
|
||||
Pair.create(WORK_TYPE_BGUSER, .1f))
|
||||
)
|
||||
);
|
||||
|
||||
@@ -357,6 +397,12 @@ class JobConcurrencyManager {
|
||||
/** Wait for this long after screen off before adjusting the job concurrency. */
|
||||
private long mScreenOffAdjustmentDelayMs = DEFAULT_SCREEN_OFF_ADJUSTMENT_DELAY_MS;
|
||||
|
||||
/**
|
||||
* The maximum number of jobs we'll attempt to have running at one time. This may occasionally
|
||||
* be exceeded based on other factors.
|
||||
*/
|
||||
private int mSteadyStateConcurrencyLimit = DEFAULT_CONCURRENCY_LIMIT;
|
||||
|
||||
/**
|
||||
* The maximum number of expedited jobs a single userId-package can have running simultaneously.
|
||||
* TOP apps are not limited.
|
||||
@@ -451,7 +497,7 @@ class JobConcurrencyManager {
|
||||
void onThirdPartyAppsCanStart() {
|
||||
final IBatteryStats batteryStats = IBatteryStats.Stub.asInterface(
|
||||
ServiceManager.getService(BatteryStats.SERVICE_NAME));
|
||||
for (int i = 0; i < STANDARD_CONCURRENCY_LIMIT; i++) {
|
||||
for (int i = 0; i < mSteadyStateConcurrencyLimit; ++i) {
|
||||
mIdleContexts.add(
|
||||
mInjector.createJobServiceContext(mService, this,
|
||||
mNotificationCoordinator, batteryStats,
|
||||
@@ -778,13 +824,14 @@ class JobConcurrencyManager {
|
||||
}
|
||||
preferredUidOnly.sort(sDeterminationComparator);
|
||||
stoppable.sort(sDeterminationComparator);
|
||||
for (int i = numRunningJobs; i < STANDARD_CONCURRENCY_LIMIT; ++i) {
|
||||
for (int i = numRunningJobs; i < mSteadyStateConcurrencyLimit; ++i) {
|
||||
final JobServiceContext jsc;
|
||||
final int numIdleContexts = mIdleContexts.size();
|
||||
if (numIdleContexts > 0) {
|
||||
jsc = mIdleContexts.removeAt(numIdleContexts - 1);
|
||||
} else {
|
||||
Slog.wtf(TAG, "Had fewer than " + STANDARD_CONCURRENCY_LIMIT + " in existence");
|
||||
// This could happen if the config is changed at runtime.
|
||||
Slog.w(TAG, "Had fewer than " + mSteadyStateConcurrencyLimit + " in existence");
|
||||
jsc = createNewJobServiceContext();
|
||||
}
|
||||
|
||||
@@ -850,7 +897,7 @@ class JobConcurrencyManager {
|
||||
ContextAssignment selectedContext = null;
|
||||
final int allWorkTypes = getJobWorkTypes(nextPending);
|
||||
final boolean pkgConcurrencyOkay = !isPkgConcurrencyLimitedLocked(nextPending);
|
||||
final boolean isInOverage = projectedRunningCount > STANDARD_CONCURRENCY_LIMIT;
|
||||
final boolean isInOverage = projectedRunningCount > mSteadyStateConcurrencyLimit;
|
||||
boolean startingJob = false;
|
||||
if (idle.size() > 0) {
|
||||
final int idx = idle.size() - 1;
|
||||
@@ -1398,7 +1445,7 @@ class JobConcurrencyManager {
|
||||
noteConcurrency();
|
||||
return;
|
||||
}
|
||||
if (mActiveServices.size() >= STANDARD_CONCURRENCY_LIMIT) {
|
||||
if (mActiveServices.size() >= mSteadyStateConcurrencyLimit) {
|
||||
final boolean respectConcurrencyLimit;
|
||||
if (!mMaxWaitTimeBypassEnabled) {
|
||||
respectConcurrencyLimit = true;
|
||||
@@ -1801,23 +1848,27 @@ class JobConcurrencyManager {
|
||||
DeviceConfig.Properties properties =
|
||||
DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER);
|
||||
|
||||
// Concurrency limit should be in the range [8, MAX_CONCURRENCY_LIMIT].
|
||||
mSteadyStateConcurrencyLimit = Math.max(8, Math.min(MAX_CONCURRENCY_LIMIT,
|
||||
properties.getInt(KEY_CONCURRENCY_LIMIT, DEFAULT_CONCURRENCY_LIMIT)));
|
||||
|
||||
mScreenOffAdjustmentDelayMs = properties.getLong(
|
||||
KEY_SCREEN_OFF_ADJUSTMENT_DELAY_MS, DEFAULT_SCREEN_OFF_ADJUSTMENT_DELAY_MS);
|
||||
|
||||
CONFIG_LIMITS_SCREEN_ON.normal.update(properties);
|
||||
CONFIG_LIMITS_SCREEN_ON.moderate.update(properties);
|
||||
CONFIG_LIMITS_SCREEN_ON.low.update(properties);
|
||||
CONFIG_LIMITS_SCREEN_ON.critical.update(properties);
|
||||
CONFIG_LIMITS_SCREEN_ON.normal.update(properties, mSteadyStateConcurrencyLimit);
|
||||
CONFIG_LIMITS_SCREEN_ON.moderate.update(properties, mSteadyStateConcurrencyLimit);
|
||||
CONFIG_LIMITS_SCREEN_ON.low.update(properties, mSteadyStateConcurrencyLimit);
|
||||
CONFIG_LIMITS_SCREEN_ON.critical.update(properties, mSteadyStateConcurrencyLimit);
|
||||
|
||||
CONFIG_LIMITS_SCREEN_OFF.normal.update(properties);
|
||||
CONFIG_LIMITS_SCREEN_OFF.moderate.update(properties);
|
||||
CONFIG_LIMITS_SCREEN_OFF.low.update(properties);
|
||||
CONFIG_LIMITS_SCREEN_OFF.critical.update(properties);
|
||||
CONFIG_LIMITS_SCREEN_OFF.normal.update(properties, mSteadyStateConcurrencyLimit);
|
||||
CONFIG_LIMITS_SCREEN_OFF.moderate.update(properties, mSteadyStateConcurrencyLimit);
|
||||
CONFIG_LIMITS_SCREEN_OFF.low.update(properties, mSteadyStateConcurrencyLimit);
|
||||
CONFIG_LIMITS_SCREEN_OFF.critical.update(properties, mSteadyStateConcurrencyLimit);
|
||||
|
||||
// Package concurrency limits must in the range [1, STANDARD_CONCURRENCY_LIMIT].
|
||||
mPkgConcurrencyLimitEj = Math.max(1, Math.min(STANDARD_CONCURRENCY_LIMIT,
|
||||
// Package concurrency limits must in the range [1, mSteadyStateConcurrencyLimit].
|
||||
mPkgConcurrencyLimitEj = Math.max(1, Math.min(mSteadyStateConcurrencyLimit,
|
||||
properties.getInt(KEY_PKG_CONCURRENCY_LIMIT_EJ, DEFAULT_PKG_CONCURRENCY_LIMIT_EJ)));
|
||||
mPkgConcurrencyLimitRegular = Math.max(1, Math.min(STANDARD_CONCURRENCY_LIMIT,
|
||||
mPkgConcurrencyLimitRegular = Math.max(1, Math.min(mSteadyStateConcurrencyLimit,
|
||||
properties.getInt(
|
||||
KEY_PKG_CONCURRENCY_LIMIT_REGULAR, DEFAULT_PKG_CONCURRENCY_LIMIT_REGULAR)));
|
||||
|
||||
@@ -1838,6 +1889,7 @@ class JobConcurrencyManager {
|
||||
try {
|
||||
pw.println("Configuration:");
|
||||
pw.increaseIndent();
|
||||
pw.print(KEY_CONCURRENCY_LIMIT, mSteadyStateConcurrencyLimit).println();
|
||||
pw.print(KEY_SCREEN_OFF_ADJUSTMENT_DELAY_MS, mScreenOffAdjustmentDelayMs).println();
|
||||
pw.print(KEY_PKG_CONCURRENCY_LIMIT_EJ, mPkgConcurrencyLimitEj).println();
|
||||
pw.print(KEY_PKG_CONCURRENCY_LIMIT_REGULAR, mPkgConcurrencyLimitRegular).println();
|
||||
@@ -2041,130 +2093,181 @@ class JobConcurrencyManager {
|
||||
|
||||
@VisibleForTesting
|
||||
static class WorkTypeConfig {
|
||||
@VisibleForTesting
|
||||
static final String KEY_PREFIX_MAX = CONFIG_KEY_PREFIX_CONCURRENCY + "max_";
|
||||
@VisibleForTesting
|
||||
static final String KEY_PREFIX_MIN = CONFIG_KEY_PREFIX_CONCURRENCY + "min_";
|
||||
private static final String KEY_PREFIX_MAX = CONFIG_KEY_PREFIX_CONCURRENCY + "max_";
|
||||
private static final String KEY_PREFIX_MIN = CONFIG_KEY_PREFIX_CONCURRENCY + "min_";
|
||||
@VisibleForTesting
|
||||
static final String KEY_PREFIX_MAX_TOTAL = CONFIG_KEY_PREFIX_CONCURRENCY + "max_total_";
|
||||
private static final String KEY_PREFIX_MAX_TOP = CONFIG_KEY_PREFIX_CONCURRENCY + "max_top_";
|
||||
private static final String KEY_PREFIX_MAX_FGS = CONFIG_KEY_PREFIX_CONCURRENCY + "max_fgs_";
|
||||
private static final String KEY_PREFIX_MAX_EJ = CONFIG_KEY_PREFIX_CONCURRENCY + "max_ej_";
|
||||
private static final String KEY_PREFIX_MAX_BG = CONFIG_KEY_PREFIX_CONCURRENCY + "max_bg_";
|
||||
private static final String KEY_PREFIX_MAX_BGUSER =
|
||||
CONFIG_KEY_PREFIX_CONCURRENCY + "max_bguser_";
|
||||
private static final String KEY_PREFIX_MAX_BGUSER_IMPORTANT =
|
||||
CONFIG_KEY_PREFIX_CONCURRENCY + "max_bguser_important_";
|
||||
private static final String KEY_PREFIX_MIN_TOP = CONFIG_KEY_PREFIX_CONCURRENCY + "min_top_";
|
||||
private static final String KEY_PREFIX_MIN_FGS = CONFIG_KEY_PREFIX_CONCURRENCY + "min_fgs_";
|
||||
private static final String KEY_PREFIX_MIN_EJ = CONFIG_KEY_PREFIX_CONCURRENCY + "min_ej_";
|
||||
private static final String KEY_PREFIX_MIN_BG = CONFIG_KEY_PREFIX_CONCURRENCY + "min_bg_";
|
||||
private static final String KEY_PREFIX_MIN_BGUSER =
|
||||
CONFIG_KEY_PREFIX_CONCURRENCY + "min_bguser_";
|
||||
private static final String KEY_PREFIX_MIN_BGUSER_IMPORTANT =
|
||||
CONFIG_KEY_PREFIX_CONCURRENCY + "min_bguser_important_";
|
||||
@VisibleForTesting
|
||||
static final String KEY_PREFIX_MAX_RATIO = KEY_PREFIX_MAX + "ratio_";
|
||||
private static final String KEY_PREFIX_MAX_RATIO_TOP = KEY_PREFIX_MAX_RATIO + "top_";
|
||||
private static final String KEY_PREFIX_MAX_RATIO_FGS = KEY_PREFIX_MAX_RATIO + "fgs_";
|
||||
private static final String KEY_PREFIX_MAX_RATIO_EJ = KEY_PREFIX_MAX_RATIO + "ej_";
|
||||
private static final String KEY_PREFIX_MAX_RATIO_BG = KEY_PREFIX_MAX_RATIO + "bg_";
|
||||
private static final String KEY_PREFIX_MAX_RATIO_BGUSER = KEY_PREFIX_MAX_RATIO + "bguser_";
|
||||
private static final String KEY_PREFIX_MAX_RATIO_BGUSER_IMPORTANT =
|
||||
KEY_PREFIX_MAX_RATIO + "bguser_important_";
|
||||
@VisibleForTesting
|
||||
static final String KEY_PREFIX_MIN_RATIO = KEY_PREFIX_MIN + "ratio_";
|
||||
private static final String KEY_PREFIX_MIN_RATIO_TOP = KEY_PREFIX_MIN_RATIO + "top_";
|
||||
private static final String KEY_PREFIX_MIN_RATIO_FGS = KEY_PREFIX_MIN_RATIO + "fgs_";
|
||||
private static final String KEY_PREFIX_MIN_RATIO_EJ = KEY_PREFIX_MIN_RATIO + "ej_";
|
||||
private static final String KEY_PREFIX_MIN_RATIO_BG = KEY_PREFIX_MIN_RATIO + "bg_";
|
||||
private static final String KEY_PREFIX_MIN_RATIO_BGUSER = KEY_PREFIX_MIN_RATIO + "bguser_";
|
||||
private static final String KEY_PREFIX_MIN_RATIO_BGUSER_IMPORTANT =
|
||||
KEY_PREFIX_MIN_RATIO + "bguser_important_";
|
||||
private final String mConfigIdentifier;
|
||||
|
||||
private int mMaxTotal;
|
||||
private final SparseIntArray mMinReservedSlots = new SparseIntArray(NUM_WORK_TYPES);
|
||||
private final SparseIntArray mMaxAllowedSlots = new SparseIntArray(NUM_WORK_TYPES);
|
||||
private final int mDefaultMaxTotal;
|
||||
private final SparseIntArray mDefaultMinReservedSlots = new SparseIntArray(NUM_WORK_TYPES);
|
||||
private final SparseIntArray mDefaultMaxAllowedSlots = new SparseIntArray(NUM_WORK_TYPES);
|
||||
// We use SparseIntArrays to store floats because there is currently no SparseFloatArray
|
||||
// available, and it doesn't seem worth it to add such a data structure just for this
|
||||
// use case. We don't use SparseDoubleArrays because DeviceConfig only supports floats and
|
||||
// converting between floats and ints is more straightforward than floats and doubles.
|
||||
private final SparseIntArray mDefaultMinReservedSlotsRatio =
|
||||
new SparseIntArray(NUM_WORK_TYPES);
|
||||
private final SparseIntArray mDefaultMaxAllowedSlotsRatio =
|
||||
new SparseIntArray(NUM_WORK_TYPES);
|
||||
|
||||
WorkTypeConfig(@NonNull String configIdentifier, int defaultMaxTotal,
|
||||
List<Pair<Integer, Integer>> defaultMin, List<Pair<Integer, Integer>> defaultMax) {
|
||||
WorkTypeConfig(@NonNull String configIdentifier,
|
||||
int steadyStateConcurrencyLimit, int defaultMaxTotal,
|
||||
List<Pair<Integer, Float>> defaultMinRatio,
|
||||
List<Pair<Integer, Float>> defaultMaxRatio) {
|
||||
mConfigIdentifier = configIdentifier;
|
||||
mDefaultMaxTotal = mMaxTotal = Math.min(defaultMaxTotal, STANDARD_CONCURRENCY_LIMIT);
|
||||
mDefaultMaxTotal = mMaxTotal = Math.min(defaultMaxTotal, steadyStateConcurrencyLimit);
|
||||
int numReserved = 0;
|
||||
for (int i = defaultMin.size() - 1; i >= 0; --i) {
|
||||
mDefaultMinReservedSlots.put(defaultMin.get(i).first, defaultMin.get(i).second);
|
||||
numReserved += defaultMin.get(i).second;
|
||||
for (int i = defaultMinRatio.size() - 1; i >= 0; --i) {
|
||||
final float ratio = defaultMinRatio.get(i).second;
|
||||
final int wt = defaultMinRatio.get(i).first;
|
||||
if (ratio < 0 || 1 <= ratio) {
|
||||
// 1 means to reserve everything. This shouldn't be allowed.
|
||||
// We only create new configs on boot, so this should trigger during development
|
||||
// (before the code gets checked in), so this makes sure the hard-coded defaults
|
||||
// make sense. DeviceConfig values will be handled gracefully in update().
|
||||
throw new IllegalArgumentException("Invalid default min ratio: wt=" + wt
|
||||
+ " minRatio=" + ratio);
|
||||
}
|
||||
mDefaultMinReservedSlotsRatio.put(wt, Float.floatToRawIntBits(ratio));
|
||||
numReserved += mMaxTotal * ratio;
|
||||
}
|
||||
if (mDefaultMaxTotal < 0 || numReserved > mDefaultMaxTotal) {
|
||||
// We only create new configs on boot, so this should trigger during development
|
||||
// (before the code gets checked in), so this makes sure the hard-coded defaults
|
||||
// make sense. DeviceConfig values will be handled gracefully in update().
|
||||
throw new IllegalArgumentException("Invalid default config: t=" + defaultMaxTotal
|
||||
+ " min=" + defaultMin + " max=" + defaultMax);
|
||||
+ " min=" + defaultMinRatio + " max=" + defaultMaxRatio);
|
||||
}
|
||||
for (int i = defaultMax.size() - 1; i >= 0; --i) {
|
||||
mDefaultMaxAllowedSlots.put(defaultMax.get(i).first, defaultMax.get(i).second);
|
||||
for (int i = defaultMaxRatio.size() - 1; i >= 0; --i) {
|
||||
final float ratio = defaultMaxRatio.get(i).second;
|
||||
final int wt = defaultMaxRatio.get(i).first;
|
||||
final float minRatio =
|
||||
Float.intBitsToFloat(mDefaultMinReservedSlotsRatio.get(wt, 0));
|
||||
if (ratio < minRatio || ratio <= 0) {
|
||||
// Max ratio shouldn't be <= 0 or less than minRatio.
|
||||
throw new IllegalArgumentException("Invalid default config:"
|
||||
+ " t=" + defaultMaxTotal
|
||||
+ " min=" + defaultMinRatio + " max=" + defaultMaxRatio);
|
||||
}
|
||||
mDefaultMaxAllowedSlotsRatio.put(wt, Float.floatToRawIntBits(ratio));
|
||||
}
|
||||
update(new DeviceConfig.Properties.Builder(
|
||||
DeviceConfig.NAMESPACE_JOB_SCHEDULER).build());
|
||||
DeviceConfig.NAMESPACE_JOB_SCHEDULER).build(), steadyStateConcurrencyLimit);
|
||||
}
|
||||
|
||||
void update(@NonNull DeviceConfig.Properties properties) {
|
||||
// Ensure total in the range [1, STANDARD_CONCURRENCY_LIMIT].
|
||||
mMaxTotal = Math.max(1, Math.min(STANDARD_CONCURRENCY_LIMIT,
|
||||
void update(@NonNull DeviceConfig.Properties properties, int steadyStateConcurrencyLimit) {
|
||||
// Ensure total in the range [1, mSteadyStateConcurrencyLimit].
|
||||
mMaxTotal = Math.max(1, Math.min(steadyStateConcurrencyLimit,
|
||||
properties.getInt(KEY_PREFIX_MAX_TOTAL + mConfigIdentifier, mDefaultMaxTotal)));
|
||||
|
||||
final int oneIntBits = Float.floatToIntBits(1);
|
||||
|
||||
mMaxAllowedSlots.clear();
|
||||
// Ensure they're in the range [1, total].
|
||||
final int maxTop = Math.max(1, Math.min(mMaxTotal,
|
||||
properties.getInt(KEY_PREFIX_MAX_TOP + mConfigIdentifier,
|
||||
mDefaultMaxAllowedSlots.get(WORK_TYPE_TOP, mMaxTotal))));
|
||||
final int maxTop = getMaxValue(properties,
|
||||
KEY_PREFIX_MAX_RATIO_TOP + mConfigIdentifier, WORK_TYPE_TOP, oneIntBits);
|
||||
mMaxAllowedSlots.put(WORK_TYPE_TOP, maxTop);
|
||||
final int maxFgs = Math.max(1, Math.min(mMaxTotal,
|
||||
properties.getInt(KEY_PREFIX_MAX_FGS + mConfigIdentifier,
|
||||
mDefaultMaxAllowedSlots.get(WORK_TYPE_FGS, mMaxTotal))));
|
||||
final int maxFgs = getMaxValue(properties,
|
||||
KEY_PREFIX_MAX_RATIO_FGS + mConfigIdentifier, WORK_TYPE_FGS, oneIntBits);
|
||||
mMaxAllowedSlots.put(WORK_TYPE_FGS, maxFgs);
|
||||
final int maxEj = Math.max(1, Math.min(mMaxTotal,
|
||||
properties.getInt(KEY_PREFIX_MAX_EJ + mConfigIdentifier,
|
||||
mDefaultMaxAllowedSlots.get(WORK_TYPE_EJ, mMaxTotal))));
|
||||
final int maxEj = getMaxValue(properties,
|
||||
KEY_PREFIX_MAX_RATIO_EJ + mConfigIdentifier, WORK_TYPE_EJ, oneIntBits);
|
||||
mMaxAllowedSlots.put(WORK_TYPE_EJ, maxEj);
|
||||
final int maxBg = Math.max(1, Math.min(mMaxTotal,
|
||||
properties.getInt(KEY_PREFIX_MAX_BG + mConfigIdentifier,
|
||||
mDefaultMaxAllowedSlots.get(WORK_TYPE_BG, mMaxTotal))));
|
||||
final int maxBg = getMaxValue(properties,
|
||||
KEY_PREFIX_MAX_RATIO_BG + mConfigIdentifier, WORK_TYPE_BG, oneIntBits);
|
||||
mMaxAllowedSlots.put(WORK_TYPE_BG, maxBg);
|
||||
final int maxBgUserImp = Math.max(1, Math.min(mMaxTotal,
|
||||
properties.getInt(KEY_PREFIX_MAX_BGUSER_IMPORTANT + mConfigIdentifier,
|
||||
mDefaultMaxAllowedSlots.get(WORK_TYPE_BGUSER_IMPORTANT, mMaxTotal))));
|
||||
final int maxBgUserImp = getMaxValue(properties,
|
||||
KEY_PREFIX_MAX_RATIO_BGUSER_IMPORTANT + mConfigIdentifier,
|
||||
WORK_TYPE_BGUSER_IMPORTANT, oneIntBits);
|
||||
mMaxAllowedSlots.put(WORK_TYPE_BGUSER_IMPORTANT, maxBgUserImp);
|
||||
final int maxBgUser = Math.max(1, Math.min(mMaxTotal,
|
||||
properties.getInt(KEY_PREFIX_MAX_BGUSER + mConfigIdentifier,
|
||||
mDefaultMaxAllowedSlots.get(WORK_TYPE_BGUSER, mMaxTotal))));
|
||||
final int maxBgUser = getMaxValue(properties,
|
||||
KEY_PREFIX_MAX_RATIO_BGUSER + mConfigIdentifier, WORK_TYPE_BGUSER, oneIntBits);
|
||||
mMaxAllowedSlots.put(WORK_TYPE_BGUSER, maxBgUser);
|
||||
|
||||
int remaining = mMaxTotal;
|
||||
mMinReservedSlots.clear();
|
||||
// Ensure top is in the range [1, min(maxTop, total)]
|
||||
final int minTop = Math.max(1, Math.min(Math.min(maxTop, mMaxTotal),
|
||||
properties.getInt(KEY_PREFIX_MIN_TOP + mConfigIdentifier,
|
||||
mDefaultMinReservedSlots.get(WORK_TYPE_TOP))));
|
||||
final int minTop = getMinValue(properties,
|
||||
KEY_PREFIX_MIN_RATIO_TOP + mConfigIdentifier, WORK_TYPE_TOP,
|
||||
1, Math.min(maxTop, mMaxTotal));
|
||||
mMinReservedSlots.put(WORK_TYPE_TOP, minTop);
|
||||
remaining -= minTop;
|
||||
// Ensure fgs is in the range [0, min(maxFgs, remaining)]
|
||||
final int minFgs = Math.max(0, Math.min(Math.min(maxFgs, remaining),
|
||||
properties.getInt(KEY_PREFIX_MIN_FGS + mConfigIdentifier,
|
||||
mDefaultMinReservedSlots.get(WORK_TYPE_FGS))));
|
||||
final int minFgs = getMinValue(properties,
|
||||
KEY_PREFIX_MIN_RATIO_FGS + mConfigIdentifier, WORK_TYPE_FGS,
|
||||
0, Math.min(maxFgs, remaining));
|
||||
mMinReservedSlots.put(WORK_TYPE_FGS, minFgs);
|
||||
remaining -= minFgs;
|
||||
// Ensure ej is in the range [0, min(maxEj, remaining)]
|
||||
final int minEj = Math.max(0, Math.min(Math.min(maxEj, remaining),
|
||||
properties.getInt(KEY_PREFIX_MIN_EJ + mConfigIdentifier,
|
||||
mDefaultMinReservedSlots.get(WORK_TYPE_EJ))));
|
||||
final int minEj = getMinValue(properties,
|
||||
KEY_PREFIX_MIN_RATIO_EJ + mConfigIdentifier, WORK_TYPE_EJ,
|
||||
0, Math.min(maxEj, remaining));
|
||||
mMinReservedSlots.put(WORK_TYPE_EJ, minEj);
|
||||
remaining -= minEj;
|
||||
// Ensure bg is in the range [0, min(maxBg, remaining)]
|
||||
final int minBg = Math.max(0, Math.min(Math.min(maxBg, remaining),
|
||||
properties.getInt(KEY_PREFIX_MIN_BG + mConfigIdentifier,
|
||||
mDefaultMinReservedSlots.get(WORK_TYPE_BG))));
|
||||
final int minBg = getMinValue(properties,
|
||||
KEY_PREFIX_MIN_RATIO_BG + mConfigIdentifier, WORK_TYPE_BG,
|
||||
0, Math.min(maxBg, remaining));
|
||||
mMinReservedSlots.put(WORK_TYPE_BG, minBg);
|
||||
remaining -= minBg;
|
||||
// Ensure bg user imp is in the range [0, min(maxBgUserImp, remaining)]
|
||||
final int minBgUserImp = Math.max(0, Math.min(Math.min(maxBgUserImp, remaining),
|
||||
properties.getInt(KEY_PREFIX_MIN_BGUSER_IMPORTANT + mConfigIdentifier,
|
||||
mDefaultMinReservedSlots.get(WORK_TYPE_BGUSER_IMPORTANT, 0))));
|
||||
final int minBgUserImp = getMinValue(properties,
|
||||
KEY_PREFIX_MIN_RATIO_BGUSER_IMPORTANT + mConfigIdentifier,
|
||||
WORK_TYPE_BGUSER_IMPORTANT, 0, Math.min(maxBgUserImp, remaining));
|
||||
mMinReservedSlots.put(WORK_TYPE_BGUSER_IMPORTANT, minBgUserImp);
|
||||
remaining -= minBgUserImp;
|
||||
// Ensure bg user is in the range [0, min(maxBgUser, remaining)]
|
||||
final int minBgUser = Math.max(0, Math.min(Math.min(maxBgUser, remaining),
|
||||
properties.getInt(KEY_PREFIX_MIN_BGUSER + mConfigIdentifier,
|
||||
mDefaultMinReservedSlots.get(WORK_TYPE_BGUSER, 0))));
|
||||
final int minBgUser = getMinValue(properties,
|
||||
KEY_PREFIX_MIN_RATIO_BGUSER + mConfigIdentifier, WORK_TYPE_BGUSER,
|
||||
0, Math.min(maxBgUser, remaining));
|
||||
mMinReservedSlots.put(WORK_TYPE_BGUSER, minBgUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the calculated max value for the work type.
|
||||
* @param defaultFloatInIntBits A {@code float} value in int bits representation (using
|
||||
* {@link Float#floatToIntBits(float)}.
|
||||
*/
|
||||
private int getMaxValue(@NonNull DeviceConfig.Properties properties, @NonNull String key,
|
||||
int workType, int defaultFloatInIntBits) {
|
||||
final float maxRatio = Math.min(1, properties.getFloat(key,
|
||||
Float.intBitsToFloat(
|
||||
mDefaultMaxAllowedSlotsRatio.get(workType, defaultFloatInIntBits))));
|
||||
// Max values should be in the range [1, total].
|
||||
return Math.max(1, (int) (mMaxTotal * maxRatio));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the calculated min value for the work type.
|
||||
*/
|
||||
private int getMinValue(@NonNull DeviceConfig.Properties properties, @NonNull String key,
|
||||
int workType, int lowerLimit, int upperLimit) {
|
||||
final float minRatio = Math.min(1,
|
||||
properties.getFloat(key,
|
||||
Float.intBitsToFloat(mDefaultMinReservedSlotsRatio.get(workType))));
|
||||
return Math.max(lowerLimit, Math.min(upperLimit, (int) (mMaxTotal * minRatio)));
|
||||
}
|
||||
|
||||
int getMaxTotal() {
|
||||
return mMaxTotal;
|
||||
}
|
||||
@@ -2179,29 +2282,37 @@ class JobConcurrencyManager {
|
||||
|
||||
void dump(IndentingPrintWriter pw) {
|
||||
pw.print(KEY_PREFIX_MAX_TOTAL + mConfigIdentifier, mMaxTotal).println();
|
||||
pw.print(KEY_PREFIX_MIN_TOP + mConfigIdentifier, mMinReservedSlots.get(WORK_TYPE_TOP))
|
||||
pw.print(KEY_PREFIX_MIN_RATIO_TOP + mConfigIdentifier,
|
||||
mMinReservedSlots.get(WORK_TYPE_TOP))
|
||||
.println();
|
||||
pw.print(KEY_PREFIX_MAX_TOP + mConfigIdentifier, mMaxAllowedSlots.get(WORK_TYPE_TOP))
|
||||
pw.print(KEY_PREFIX_MAX_RATIO_TOP + mConfigIdentifier,
|
||||
mMaxAllowedSlots.get(WORK_TYPE_TOP))
|
||||
.println();
|
||||
pw.print(KEY_PREFIX_MIN_FGS + mConfigIdentifier, mMinReservedSlots.get(WORK_TYPE_FGS))
|
||||
pw.print(KEY_PREFIX_MIN_RATIO_FGS + mConfigIdentifier,
|
||||
mMinReservedSlots.get(WORK_TYPE_FGS))
|
||||
.println();
|
||||
pw.print(KEY_PREFIX_MAX_FGS + mConfigIdentifier, mMaxAllowedSlots.get(WORK_TYPE_FGS))
|
||||
pw.print(KEY_PREFIX_MAX_RATIO_FGS + mConfigIdentifier,
|
||||
mMaxAllowedSlots.get(WORK_TYPE_FGS))
|
||||
.println();
|
||||
pw.print(KEY_PREFIX_MIN_EJ + mConfigIdentifier, mMinReservedSlots.get(WORK_TYPE_EJ))
|
||||
pw.print(KEY_PREFIX_MIN_RATIO_EJ + mConfigIdentifier,
|
||||
mMinReservedSlots.get(WORK_TYPE_EJ))
|
||||
.println();
|
||||
pw.print(KEY_PREFIX_MAX_EJ + mConfigIdentifier, mMaxAllowedSlots.get(WORK_TYPE_EJ))
|
||||
pw.print(KEY_PREFIX_MAX_RATIO_EJ + mConfigIdentifier,
|
||||
mMaxAllowedSlots.get(WORK_TYPE_EJ))
|
||||
.println();
|
||||
pw.print(KEY_PREFIX_MIN_BG + mConfigIdentifier, mMinReservedSlots.get(WORK_TYPE_BG))
|
||||
pw.print(KEY_PREFIX_MIN_RATIO_BG + mConfigIdentifier,
|
||||
mMinReservedSlots.get(WORK_TYPE_BG))
|
||||
.println();
|
||||
pw.print(KEY_PREFIX_MAX_BG + mConfigIdentifier, mMaxAllowedSlots.get(WORK_TYPE_BG))
|
||||
pw.print(KEY_PREFIX_MAX_RATIO_BG + mConfigIdentifier,
|
||||
mMaxAllowedSlots.get(WORK_TYPE_BG))
|
||||
.println();
|
||||
pw.print(KEY_PREFIX_MIN_BGUSER + mConfigIdentifier,
|
||||
pw.print(KEY_PREFIX_MIN_RATIO_BGUSER + mConfigIdentifier,
|
||||
mMinReservedSlots.get(WORK_TYPE_BGUSER_IMPORTANT)).println();
|
||||
pw.print(KEY_PREFIX_MAX_BGUSER + mConfigIdentifier,
|
||||
pw.print(KEY_PREFIX_MAX_RATIO_BGUSER + mConfigIdentifier,
|
||||
mMaxAllowedSlots.get(WORK_TYPE_BGUSER_IMPORTANT)).println();
|
||||
pw.print(KEY_PREFIX_MIN_BGUSER + mConfigIdentifier,
|
||||
pw.print(KEY_PREFIX_MIN_RATIO_BGUSER + mConfigIdentifier,
|
||||
mMinReservedSlots.get(WORK_TYPE_BGUSER)).println();
|
||||
pw.print(KEY_PREFIX_MAX_BGUSER + mConfigIdentifier,
|
||||
pw.print(KEY_PREFIX_MAX_RATIO_BGUSER + mConfigIdentifier,
|
||||
mMaxAllowedSlots.get(WORK_TYPE_BGUSER)).println();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ public final class JobConcurrencyManagerTest {
|
||||
mJobConcurrencyManager.prepareForAssignmentDeterminationLocked(
|
||||
idle, preferredUidOnly, stoppable, assignmentInfo);
|
||||
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, idle.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, idle.size());
|
||||
assertEquals(0, preferredUidOnly.size());
|
||||
assertEquals(0, stoppable.size());
|
||||
assertEquals(0, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
|
||||
@@ -222,7 +222,7 @@ public final class JobConcurrencyManagerTest {
|
||||
|
||||
@Test
|
||||
public void testPrepareForAssignmentDetermination_onlyPendingJobs() {
|
||||
for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
|
||||
for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
|
||||
JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE + i);
|
||||
mPendingJobQueue.add(job);
|
||||
}
|
||||
@@ -235,7 +235,7 @@ public final class JobConcurrencyManagerTest {
|
||||
mJobConcurrencyManager.prepareForAssignmentDeterminationLocked(
|
||||
idle, preferredUidOnly, stoppable, assignmentInfo);
|
||||
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, idle.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, idle.size());
|
||||
assertEquals(0, preferredUidOnly.size());
|
||||
assertEquals(0, stoppable.size());
|
||||
assertEquals(0, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
|
||||
@@ -244,7 +244,7 @@ public final class JobConcurrencyManagerTest {
|
||||
|
||||
@Test
|
||||
public void testPrepareForAssignmentDetermination_onlyPreferredUidOnly() {
|
||||
for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
|
||||
for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
|
||||
JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE + i);
|
||||
mJobConcurrencyManager.addRunningJobForTesting(job);
|
||||
}
|
||||
@@ -262,7 +262,7 @@ public final class JobConcurrencyManagerTest {
|
||||
idle, preferredUidOnly, stoppable, assignmentInfo);
|
||||
|
||||
assertEquals(0, idle.size());
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
assertEquals(0, stoppable.size());
|
||||
assertEquals(0, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
|
||||
assertEquals(0, assignmentInfo.numRunningImmediacyPrivileged);
|
||||
@@ -270,7 +270,7 @@ public final class JobConcurrencyManagerTest {
|
||||
|
||||
@Test
|
||||
public void testPrepareForAssignmentDetermination_onlyStartedWithImmediacyPrivilege() {
|
||||
for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
|
||||
for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
|
||||
JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE + i);
|
||||
job.startedWithImmediacyPrivilege = true;
|
||||
mJobConcurrencyManager.addRunningJobForTesting(job);
|
||||
@@ -289,19 +289,19 @@ public final class JobConcurrencyManagerTest {
|
||||
idle, preferredUidOnly, stoppable, assignmentInfo);
|
||||
|
||||
assertEquals(0, idle.size());
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT / 2, preferredUidOnly.size());
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT / 2, stoppable.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT / 2, preferredUidOnly.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT / 2, stoppable.size());
|
||||
assertEquals(0, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT,
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
|
||||
assignmentInfo.numRunningImmediacyPrivileged);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetermineAssignments_allRegular() throws Exception {
|
||||
setConcurrencyConfig(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT,
|
||||
new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT));
|
||||
setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
|
||||
new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT));
|
||||
final ArraySet<JobStatus> jobs = new ArraySet<>();
|
||||
for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
|
||||
for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
|
||||
final int uid = mDefaultUserId * UserHandle.PER_USER_RANGE + i;
|
||||
final String sourcePkgName = "com.source.package." + UserHandle.getAppId(uid);
|
||||
setPackageUid(sourcePkgName, uid);
|
||||
@@ -322,7 +322,7 @@ public final class JobConcurrencyManagerTest {
|
||||
.determineAssignmentsLocked(changed, idle, preferredUidOnly, stoppable,
|
||||
assignmentInfo);
|
||||
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, changed.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, changed.size());
|
||||
for (int i = changed.size() - 1; i >= 0; --i) {
|
||||
jobs.remove(changed.valueAt(i).newJob);
|
||||
}
|
||||
@@ -332,16 +332,16 @@ public final class JobConcurrencyManagerTest {
|
||||
@Test
|
||||
public void testDetermineAssignments_allPreferredUidOnly_shortTimeLeft() throws Exception {
|
||||
mConfigBuilder.setBoolean(JobConcurrencyManager.KEY_ENABLE_MAX_WAIT_TIME_BYPASS, true);
|
||||
setConcurrencyConfig(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT,
|
||||
new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT));
|
||||
for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT * 2; ++i) {
|
||||
setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
|
||||
new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT));
|
||||
for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT * 2; ++i) {
|
||||
final int uid = mDefaultUserId * UserHandle.PER_USER_RANGE + i;
|
||||
final String sourcePkgName = "com.source.package." + UserHandle.getAppId(uid);
|
||||
setPackageUid(sourcePkgName, uid);
|
||||
final JobStatus job = createJob(uid, sourcePkgName);
|
||||
spyOn(job);
|
||||
doReturn(i % 2 == 0).when(job).shouldTreatAsExpeditedJob();
|
||||
if (i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT) {
|
||||
if (i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT) {
|
||||
mJobConcurrencyManager.addRunningJobForTesting(job);
|
||||
} else {
|
||||
mPendingJobQueue.add(job);
|
||||
@@ -366,30 +366,30 @@ public final class JobConcurrencyManagerTest {
|
||||
mJobConcurrencyManager.prepareForAssignmentDeterminationLocked(
|
||||
idle, preferredUidOnly, stoppable, assignmentInfo);
|
||||
assertEquals(remainingTimeMs, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
|
||||
mJobConcurrencyManager
|
||||
.determineAssignmentsLocked(changed, idle, preferredUidOnly, stoppable,
|
||||
assignmentInfo);
|
||||
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
assertEquals(0, changed.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetermineAssignments_allPreferredUidOnly_mediumTimeLeft() throws Exception {
|
||||
mConfigBuilder.setBoolean(JobConcurrencyManager.KEY_ENABLE_MAX_WAIT_TIME_BYPASS, true);
|
||||
setConcurrencyConfig(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT,
|
||||
new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT));
|
||||
setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
|
||||
new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT));
|
||||
final ArraySet<JobStatus> jobs = new ArraySet<>();
|
||||
for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT * 2; ++i) {
|
||||
for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT * 2; ++i) {
|
||||
final int uid = mDefaultUserId * UserHandle.PER_USER_RANGE + i;
|
||||
final String sourcePkgName = "com.source.package." + UserHandle.getAppId(uid);
|
||||
setPackageUid(sourcePkgName, uid);
|
||||
final JobStatus job = createJob(uid, sourcePkgName);
|
||||
spyOn(job);
|
||||
doReturn(i % 2 == 0).when(job).shouldTreatAsExpeditedJob();
|
||||
if (i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT) {
|
||||
if (i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT) {
|
||||
mJobConcurrencyManager.addRunningJobForTesting(job);
|
||||
} else {
|
||||
mPendingJobQueue.add(job);
|
||||
@@ -417,17 +417,17 @@ public final class JobConcurrencyManagerTest {
|
||||
mJobConcurrencyManager.prepareForAssignmentDeterminationLocked(
|
||||
idle, preferredUidOnly, stoppable, assignmentInfo);
|
||||
assertEquals(remainingTimeMs, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
|
||||
mJobConcurrencyManager
|
||||
.determineAssignmentsLocked(changed, idle, preferredUidOnly, stoppable,
|
||||
assignmentInfo);
|
||||
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
for (int i = changed.size() - 1; i >= 0; --i) {
|
||||
jobs.remove(changed.valueAt(i).newJob);
|
||||
}
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT - 1, jobs.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT - 1, jobs.size());
|
||||
assertEquals(1, changed.size());
|
||||
JobStatus assignedJob = changed.valueAt(0).newJob;
|
||||
assertTrue(assignedJob.shouldTreatAsExpeditedJob());
|
||||
@@ -436,17 +436,17 @@ public final class JobConcurrencyManagerTest {
|
||||
@Test
|
||||
public void testDetermineAssignments_allPreferredUidOnly_longTimeLeft() throws Exception {
|
||||
mConfigBuilder.setBoolean(JobConcurrencyManager.KEY_ENABLE_MAX_WAIT_TIME_BYPASS, true);
|
||||
setConcurrencyConfig(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT,
|
||||
new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT));
|
||||
setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
|
||||
new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT));
|
||||
final ArraySet<JobStatus> jobs = new ArraySet<>();
|
||||
for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT * 2; ++i) {
|
||||
for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT * 2; ++i) {
|
||||
final int uid = mDefaultUserId * UserHandle.PER_USER_RANGE + i;
|
||||
final String sourcePkgName = "com.source.package." + UserHandle.getAppId(uid);
|
||||
setPackageUid(sourcePkgName, uid);
|
||||
final JobStatus job = createJob(uid, sourcePkgName);
|
||||
spyOn(job);
|
||||
doReturn(i % 2 == 0).when(job).shouldTreatAsExpeditedJob();
|
||||
if (i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT) {
|
||||
if (i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT) {
|
||||
mJobConcurrencyManager.addRunningJobForTesting(job);
|
||||
} else {
|
||||
mPendingJobQueue.add(job);
|
||||
@@ -473,13 +473,13 @@ public final class JobConcurrencyManagerTest {
|
||||
mJobConcurrencyManager.prepareForAssignmentDeterminationLocked(
|
||||
idle, preferredUidOnly, stoppable, assignmentInfo);
|
||||
assertEquals(remainingTimeMs, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
|
||||
mJobConcurrencyManager
|
||||
.determineAssignmentsLocked(changed, idle, preferredUidOnly, stoppable,
|
||||
assignmentInfo);
|
||||
|
||||
assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
|
||||
// Depending on iteration order, we may create 1 or 2 contexts.
|
||||
final long numAssignedJobs = changed.size();
|
||||
assertTrue(numAssignedJobs > 0);
|
||||
@@ -488,7 +488,7 @@ public final class JobConcurrencyManagerTest {
|
||||
jobs.remove(changed.valueAt(i).newJob);
|
||||
}
|
||||
assertEquals(numAssignedJobs,
|
||||
JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT - jobs.size());
|
||||
JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT - jobs.size());
|
||||
JobStatus firstAssignedJob = changed.valueAt(0).newJob;
|
||||
if (!firstAssignedJob.shouldTreatAsExpeditedJob()) {
|
||||
assertEquals(2, numAssignedJobs);
|
||||
@@ -538,14 +538,14 @@ public final class JobConcurrencyManagerTest {
|
||||
assertFalse(mJobConcurrencyManager.isPkgConcurrencyLimitedLocked(topJob));
|
||||
|
||||
// Pending jobs shouldn't affect TOP job's status.
|
||||
for (int i = 1; i <= JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
|
||||
for (int i = 1; i <= JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
|
||||
final JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE + i);
|
||||
mPendingJobQueue.add(job);
|
||||
}
|
||||
assertFalse(mJobConcurrencyManager.isPkgConcurrencyLimitedLocked(topJob));
|
||||
|
||||
// Already running jobs shouldn't affect TOP job's status.
|
||||
for (int i = 1; i <= JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
|
||||
for (int i = 1; i <= JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
|
||||
final JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE, i);
|
||||
mJobConcurrencyManager.addRunningJobForTesting(job);
|
||||
}
|
||||
@@ -605,9 +605,9 @@ public final class JobConcurrencyManagerTest {
|
||||
spyOn(testEj);
|
||||
doReturn(true).when(testEj).shouldTreatAsExpeditedJob();
|
||||
|
||||
setConcurrencyConfig(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT);
|
||||
setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT);
|
||||
|
||||
for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
|
||||
for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
|
||||
final JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE + i, i + 1);
|
||||
mPendingJobQueue.add(job);
|
||||
}
|
||||
@@ -887,12 +887,14 @@ public final class JobConcurrencyManagerTest {
|
||||
mConfigBuilder
|
||||
.setInt(WorkTypeConfig.KEY_PREFIX_MAX_TOTAL + identifier, total);
|
||||
for (TypeConfig config : typeConfigs) {
|
||||
mConfigBuilder.setInt(
|
||||
WorkTypeConfig.KEY_PREFIX_MAX + config.workTypeString + "_" + identifier,
|
||||
config.max);
|
||||
mConfigBuilder.setInt(
|
||||
WorkTypeConfig.KEY_PREFIX_MIN + config.workTypeString + "_" + identifier,
|
||||
config.min);
|
||||
mConfigBuilder.setFloat(
|
||||
WorkTypeConfig.KEY_PREFIX_MAX_RATIO + config.workTypeString + "_"
|
||||
+ identifier,
|
||||
(float) config.max / total);
|
||||
mConfigBuilder.setFloat(
|
||||
WorkTypeConfig.KEY_PREFIX_MIN_RATIO + config.workTypeString + "_"
|
||||
+ identifier,
|
||||
(float) config.min / total);
|
||||
}
|
||||
}
|
||||
updateDeviceConfig();
|
||||
|
||||
@@ -57,14 +57,14 @@ public class BiasSchedulingTest extends AndroidTestCase {
|
||||
}
|
||||
|
||||
public void testLowerBiasJobPreempted() throws Exception {
|
||||
for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
|
||||
for (int i = 0; i < JobConcurrencyManager.MAX_CONCURRENCY_LIMIT; ++i) {
|
||||
JobInfo job = new JobInfo.Builder(100 + i, sJobServiceComponent)
|
||||
.setBias(LOW_BIAS)
|
||||
.setOverrideDeadline(0)
|
||||
.build();
|
||||
mJobScheduler.schedule(job);
|
||||
}
|
||||
final int higherBiasJobId = 100 + JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT;
|
||||
final int higherBiasJobId = 100 + JobConcurrencyManager.MAX_CONCURRENCY_LIMIT;
|
||||
JobInfo jobHigher = new JobInfo.Builder(higherBiasJobId, sJobServiceComponent)
|
||||
.setBias(HIGH_BIAS)
|
||||
.setMinimumLatency(2000)
|
||||
@@ -88,14 +88,14 @@ public class BiasSchedulingTest extends AndroidTestCase {
|
||||
}
|
||||
|
||||
public void testHigherBiasJobNotPreempted() throws Exception {
|
||||
for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
|
||||
for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
|
||||
JobInfo job = new JobInfo.Builder(100 + i, sJobServiceComponent)
|
||||
.setBias(HIGH_BIAS)
|
||||
.setOverrideDeadline(0)
|
||||
.build();
|
||||
mJobScheduler.schedule(job);
|
||||
}
|
||||
final int lowerBiasJobId = 100 + JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT;
|
||||
final int lowerBiasJobId = 100 + JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT;
|
||||
JobInfo jobLower = new JobInfo.Builder(lowerBiasJobId, sJobServiceComponent)
|
||||
.setBias(LOW_BIAS)
|
||||
.setMinimumLatency(2000)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.job;
|
||||
|
||||
import static com.android.server.job.JobConcurrencyManager.MAX_CONCURRENCY_LIMIT;
|
||||
import static com.android.server.job.JobConcurrencyManager.NUM_WORK_TYPES;
|
||||
import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_BG;
|
||||
import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_BGUSER;
|
||||
@@ -191,10 +192,10 @@ public class WorkCountTrackerTest {
|
||||
}
|
||||
|
||||
private void recount(Jobs jobs, int totalMax,
|
||||
@NonNull List<Pair<Integer, Integer>> minLimits,
|
||||
@NonNull List<Pair<Integer, Integer>> maxLimits) {
|
||||
@NonNull List<Pair<Integer, Float>> minLimitRatios,
|
||||
@NonNull List<Pair<Integer, Float>> maxLimitRatios) {
|
||||
mWorkCountTracker.setConfig(new JobConcurrencyManager.WorkTypeConfig(
|
||||
"test", totalMax, minLimits, maxLimits));
|
||||
"test", MAX_CONCURRENCY_LIMIT, totalMax, minLimitRatios, maxLimitRatios));
|
||||
mWorkCountTracker.resetCounts();
|
||||
|
||||
for (int i = 0; i < jobs.running.size(); ++i) {
|
||||
@@ -259,18 +260,18 @@ public class WorkCountTrackerTest {
|
||||
* Used by the following testRandom* tests.
|
||||
*/
|
||||
private void checkRandom(Jobs jobs, int numTests, int totalMax,
|
||||
@NonNull List<Pair<Integer, Integer>> minLimits,
|
||||
@NonNull List<Pair<Integer, Integer>> maxLimits,
|
||||
@NonNull List<Pair<Integer, Float>> minLimitRatios,
|
||||
@NonNull List<Pair<Integer, Float>> maxLimitRatios,
|
||||
double probStart, double[] typeCdf, double[] numTypesCdf, double probStop) {
|
||||
int minExpected = 0;
|
||||
for (Pair<Integer, Integer> minLimit : minLimits) {
|
||||
minExpected = Math.min(minLimit.second, minExpected);
|
||||
for (Pair<Integer, Float> minLimit : minLimitRatios) {
|
||||
minExpected = Math.min((int) (minLimit.second * MAX_CONCURRENCY_LIMIT), minExpected);
|
||||
}
|
||||
for (int i = 0; i < numTests; i++) {
|
||||
jobs.maybeFinishJobs(probStop);
|
||||
jobs.maybeEnqueueJobs(probStart, typeCdf, numTypesCdf);
|
||||
|
||||
recount(jobs, totalMax, minLimits, maxLimits);
|
||||
recount(jobs, totalMax, minLimitRatios, maxLimitRatios);
|
||||
final int numPending = jobs.pendingMultiTypes.size();
|
||||
startPendingJobs(jobs);
|
||||
|
||||
@@ -284,9 +285,11 @@ public class WorkCountTrackerTest {
|
||||
}
|
||||
assertThat(totalRunning).isAtMost(totalMax);
|
||||
assertThat(totalRunning).isAtLeast(Math.min(minExpected, numPending));
|
||||
for (Pair<Integer, Integer> maxLimit : maxLimits) {
|
||||
assertWithMessage("Work type " + maxLimit.first + " is running too many jobs")
|
||||
.that(jobs.running.get(maxLimit.first)).isAtMost(maxLimit.second);
|
||||
for (Pair<Integer, Float> maxLimitRatio : maxLimitRatios) {
|
||||
final int workType = maxLimitRatio.first;
|
||||
final int maxLimit = (int) (maxLimitRatio.second * MAX_CONCURRENCY_LIMIT);
|
||||
assertWithMessage("Work type " + workType + " is running too many jobs")
|
||||
.that(jobs.running.get(workType)).isAtMost(maxLimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -302,12 +305,14 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> maxLimits = List.of(Pair.create(WORK_TYPE_BG, 4));
|
||||
final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3));
|
||||
final double probStop = 0.1;
|
||||
final double probStart = 0.1;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
EQUAL_PROBABILITY_CDF, EQUAL_PROBABILITY_CDF, probStop);
|
||||
}
|
||||
|
||||
@@ -317,15 +322,15 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 2;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
|
||||
final List<Pair<Integer, Integer>> minLimits = List.of();
|
||||
final List<Pair<Integer, Float>> minLimitRatios = List.of();
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, .5f));
|
||||
final double probStop = 0.5;
|
||||
final double[] cdf = buildWorkTypeCdf(0.5, 0, 0, 0.5, 0, 0);
|
||||
final double[] numTypesCdf = buildCdf(.5, .3, .15, .05);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -335,15 +340,15 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 2;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
|
||||
final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
|
||||
final List<Pair<Integer, Float>> minLimitRatios = List.of(Pair.create(WORK_TYPE_BG, .99f));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, .5f));
|
||||
final double probStop = 0.5;
|
||||
final double[] cdf = buildWorkTypeCdf(1.0 / 3, 0, 0, 1.0 / 3, 0, 1.0 / 3);
|
||||
final double[] numTypesCdf = buildCdf(.75, .2, .05);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -353,15 +358,15 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 10;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
|
||||
final List<Pair<Integer, Integer>> minLimits = List.of();
|
||||
final List<Pair<Integer, Float>> minLimitRatios = List.of();
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, .2f), Pair.create(WORK_TYPE_BGUSER, .1f));
|
||||
final double probStop = 0.5;
|
||||
final double[] cdf = buildWorkTypeCdf(1.0 / 3, 0, 0, 1.0 / 3, 0, 1.0 / 3);
|
||||
final double[] numTypesCdf = buildCdf(.05, .95);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -371,15 +376,17 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
|
||||
final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 2.0f / 3));
|
||||
final double probStop = 0.5;
|
||||
final double[] cdf = buildWorkTypeCdf(0.1, 0, 0, 0.8, 0.02, .08);
|
||||
final double[] numTypesCdf = buildCdf(.5, .3, .15, .05);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -389,15 +396,17 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
|
||||
final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
|
||||
final double probStop = 0.5;
|
||||
final double[] cdf = buildWorkTypeCdf(0.85, 0.05, 0, 0.1, 0, 0);
|
||||
final double[] numTypesCdf = buildCdf(1);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -407,15 +416,17 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
|
||||
final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
|
||||
final double probStop = 0.4;
|
||||
final double[] cdf = buildWorkTypeCdf(0.1, 0, 0, 0.1, 0.05, .75);
|
||||
final double[] numTypesCdf = buildCdf(0.5, 0.5);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -425,16 +436,18 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
|
||||
final List<Pair<Integer, Integer>> minLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 6));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
|
||||
final double probStop = 0.4;
|
||||
final double[] cdf = buildWorkTypeCdf(0.8, 0.1, 0, 0.05, 0, 0.05);
|
||||
final double[] numTypesCdf = buildCdf(1);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -444,16 +457,18 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
|
||||
final List<Pair<Integer, Integer>> minLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 6));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
|
||||
final double probStop = 0.5;
|
||||
final double[] cdf = buildWorkTypeCdf(0, 0, 0, 0.5, 0, 0.5);
|
||||
final double[] numTypesCdf = buildCdf(1);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -463,16 +478,18 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
|
||||
final List<Pair<Integer, Integer>> minLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 6));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
|
||||
final double probStop = 0.5;
|
||||
final double[] cdf = buildWorkTypeCdf(0, 0, 0, 0.1, 0, 0.9);
|
||||
final double[] numTypesCdf = buildCdf(0.9, 0.1);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -482,16 +499,18 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
|
||||
final List<Pair<Integer, Integer>> minLimits =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 6));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
|
||||
final double probStop = 0.5;
|
||||
final double[] cdf = buildWorkTypeCdf(0, 0, 0, 0.9, 0, 0.1);
|
||||
final double[] numTypesCdf = buildCdf(1);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -501,15 +520,16 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> maxLimits = List.of(Pair.create(WORK_TYPE_BG, 4));
|
||||
final List<Pair<Integer, Integer>> minLimits =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 2));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 1.0f / 3), Pair.create(WORK_TYPE_BG, 1.0f / 3));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3));
|
||||
final double probStop = 0.4;
|
||||
final double[] cdf = buildWorkTypeCdf(0.5, 0, 0.5, 0, 0, 0);
|
||||
final double[] numTypesCdf = buildCdf(0.1, 0.7, 0.2);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -522,16 +542,16 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 13;
|
||||
final List<Pair<Integer, Integer>> maxLimits = List.of(
|
||||
Pair.create(WORK_TYPE_EJ, 5), Pair.create(WORK_TYPE_BG, 4),
|
||||
Pair.create(WORK_TYPE_BGUSER, 3));
|
||||
final List<Pair<Integer, Integer>> minLimits =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 1));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 2.0f / 13), Pair.create(WORK_TYPE_BG, 1.0f / 13));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios = List.of(
|
||||
Pair.create(WORK_TYPE_EJ, 5.0f / 13), Pair.create(WORK_TYPE_BG, 4.0f / 13),
|
||||
Pair.create(WORK_TYPE_BGUSER, 3.0f / 13));
|
||||
final double probStop = 0.13;
|
||||
final double[] numTypesCdf = buildCdf(0, 0.05, 0.1, 0.7, 0.1, 0.05);
|
||||
final double probStart = 0.87;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
EQUAL_PROBABILITY_CDF, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -541,15 +561,16 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 5), Pair.create(WORK_TYPE_BG, 4));
|
||||
final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 5.0f / 6), Pair.create(WORK_TYPE_BG, 2.0f / 3));
|
||||
final double probStop = 0.4;
|
||||
final double[] cdf = buildWorkTypeCdf(.1, 0, 0.5, 0.35, 0, 0.05);
|
||||
final double[] numTypesCdf = buildCdf(1);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -559,17 +580,17 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 5), Pair.create(WORK_TYPE_BG, 4),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1));
|
||||
final List<Pair<Integer, Integer>> minLimits =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 2));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, .5f), Pair.create(WORK_TYPE_BG, 1.0f / 3));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 5.0f / 6), Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 6));
|
||||
final double probStop = 0.4;
|
||||
final double[] cdf = buildWorkTypeCdf(0.01, 0.09, 0.4, 0.1, 0, 0.4);
|
||||
final double[] numTypesCdf = buildCdf(0.7, 0.3);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
@@ -579,25 +600,25 @@ public class WorkCountTrackerTest {
|
||||
|
||||
final int numTests = 5000;
|
||||
final int totalMax = 7;
|
||||
final List<Pair<Integer, Integer>> maxLimits =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 5), Pair.create(WORK_TYPE_BG, 4),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1));
|
||||
final List<Pair<Integer, Integer>> minLimits =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 2));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 3.0f / 7), Pair.create(WORK_TYPE_BG, 2.0f / 7));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 5.0f / 7), Pair.create(WORK_TYPE_BG, 4.0f / 7),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1.0f / 7),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 7));
|
||||
final double probStop = 0.4;
|
||||
final double[] cdf = buildWorkTypeCdf(0.01, 0.09, 0.25, 0.05, 0.3, 0.3);
|
||||
final double[] numTypesCdf = buildCdf(0.7, 0.3);
|
||||
final double probStart = 0.5;
|
||||
|
||||
checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
|
||||
checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
|
||||
cdf, numTypesCdf, probStop);
|
||||
}
|
||||
|
||||
/** Used by the following tests */
|
||||
private void checkSimple(int totalMax,
|
||||
@NonNull List<Pair<Integer, Integer>> minLimits,
|
||||
@NonNull List<Pair<Integer, Integer>> maxLimits,
|
||||
@NonNull List<Pair<Integer, Float>> minLimitRatios,
|
||||
@NonNull List<Pair<Integer, Float>> maxLimitRatios,
|
||||
@NonNull List<Pair<Integer, Integer>> running,
|
||||
@NonNull List<Pair<Integer, Integer>> pending,
|
||||
@NonNull List<Pair<Integer, Integer>> resultRunning,
|
||||
@@ -610,17 +631,19 @@ public class WorkCountTrackerTest {
|
||||
jobs.addPending(pend.first, pend.second);
|
||||
}
|
||||
|
||||
recount(jobs, totalMax, minLimits, maxLimits);
|
||||
recount(jobs, totalMax, minLimitRatios, maxLimitRatios);
|
||||
startPendingJobs(jobs);
|
||||
|
||||
for (Pair<Integer, Integer> run : resultRunning) {
|
||||
assertWithMessage(
|
||||
"Incorrect running result for work type " + workTypeToString(run.first))
|
||||
"Incorrect running result for work type " + workTypeToString(run.first)
|
||||
+ " wanted " + run.second + ", got " + jobs.running.get(run.first))
|
||||
.that(jobs.running.get(run.first)).isEqualTo(run.second);
|
||||
}
|
||||
for (Pair<Integer, Integer> pend : resultPending) {
|
||||
assertWithMessage(
|
||||
"Incorrect pending result for work type " + workTypeToString(pend.first))
|
||||
"Incorrect pending result for work type " + workTypeToString(pend.first)
|
||||
+ " wanted " + pend.second + ", got " + jobs.pending.get(pend.first))
|
||||
.that(jobs.pending.get(pend.first)).isEqualTo(pend.second);
|
||||
}
|
||||
}
|
||||
@@ -628,16 +651,18 @@ public class WorkCountTrackerTest {
|
||||
@Test
|
||||
public void testBasic() {
|
||||
checkSimple(6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
|
||||
/* max */List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 3)),
|
||||
/* run */ List.of(),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 1)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 1)),
|
||||
/* resPen */ List.of());
|
||||
|
||||
checkSimple(6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 3)),
|
||||
/* run */ List.of(),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 6)),
|
||||
@@ -645,39 +670,40 @@ public class WorkCountTrackerTest {
|
||||
|
||||
// When there are BG jobs pending, 2 (min-BG) jobs should run.
|
||||
checkSimple(6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 3)),
|
||||
/* run */ List.of(),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 5), Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 5)));
|
||||
checkSimple(6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 4)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3)),
|
||||
/* run */ List.of(),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 3)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 1)));
|
||||
|
||||
checkSimple(8,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .25f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, .75f)),
|
||||
/* run */ List.of(),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_BG, 49)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* resPen */ List.of(Pair.create(WORK_TYPE_BG, 43)));
|
||||
|
||||
checkSimple(8,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .25f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, .75f)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 4)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_BG, 49)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* resPen */ List.of(Pair.create(WORK_TYPE_BG, 47)));
|
||||
|
||||
checkSimple(8,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .25f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, .75f)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 4)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 49), Pair.create(WORK_TYPE_BG, 49)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 4)),
|
||||
@@ -686,48 +712,52 @@ public class WorkCountTrackerTest {
|
||||
|
||||
|
||||
checkSimple(8,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .25f)),
|
||||
/* max */
|
||||
List.of(Pair.create(WORK_TYPE_TOP, .75f), Pair.create(WORK_TYPE_BG, .75f)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 4)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 49)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 4)),
|
||||
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 8), Pair.create(WORK_TYPE_BG, 49)));
|
||||
|
||||
checkSimple(8,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .25f)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_TOP, .75f), Pair.create(WORK_TYPE_BG, .75f)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 49)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 48)));
|
||||
|
||||
checkSimple(8,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 8)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_TOP, .75f), Pair.create(WORK_TYPE_BG, .25f)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 49)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 8), Pair.create(WORK_TYPE_BG, 49)));
|
||||
|
||||
checkSimple(8,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 8)),
|
||||
/* max */
|
||||
List.of(Pair.create(WORK_TYPE_TOP, .75f), Pair.create(WORK_TYPE_BG, .25f)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 49)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 8), Pair.create(WORK_TYPE_BG, 49)));
|
||||
|
||||
checkSimple(6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 4)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 6)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 3)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 6)),
|
||||
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 3)));
|
||||
|
||||
checkSimple(8,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 4)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_EJ, .25f), Pair.create(WORK_TYPE_BG, .25f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, .75f)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 6)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_EJ, 5),
|
||||
Pair.create(WORK_TYPE_BG, 3)),
|
||||
@@ -740,15 +770,16 @@ public class WorkCountTrackerTest {
|
||||
// shouldn't start new ones.
|
||||
checkSimple(5,
|
||||
/* min */ List.of(),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, .2f)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 3)),
|
||||
/* resRun */ List.of(Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 3)));
|
||||
|
||||
checkSimple(6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 3)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10),
|
||||
Pair.create(WORK_TYPE_BG, 3),
|
||||
@@ -759,8 +790,9 @@ public class WorkCountTrackerTest {
|
||||
Pair.create(WORK_TYPE_BGUSER, 3)));
|
||||
|
||||
checkSimple(6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 3)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 2.0f / 3), Pair.create(WORK_TYPE_BGUSER, .5f)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_BG, 3), Pair.create(WORK_TYPE_BGUSER, 3)),
|
||||
/* resRun */ List.of(
|
||||
@@ -769,8 +801,9 @@ public class WorkCountTrackerTest {
|
||||
Pair.create(WORK_TYPE_BG, 1), Pair.create(WORK_TYPE_BGUSER, 1)));
|
||||
|
||||
checkSimple(6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 1)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 6)),
|
||||
/* run */ List.of(Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* pen */ List.of(Pair.create(WORK_TYPE_BG, 3), Pair.create(WORK_TYPE_BGUSER, 3)),
|
||||
/* resRun */ List.of(
|
||||
@@ -778,12 +811,13 @@ public class WorkCountTrackerTest {
|
||||
/* resPen */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 1), Pair.create(WORK_TYPE_BGUSER, 2)));
|
||||
|
||||
Log.d(TAG, "START***#*#*#*#*#*#**#*");
|
||||
// Test multi-types
|
||||
checkSimple(6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 2)),
|
||||
/* min */
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 1.0f / 3), Pair.create(WORK_TYPE_BG, 1.0f / 3)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 1)),
|
||||
Pair.create(WORK_TYPE_BG, 2.0f / 3),
|
||||
Pair.create(WORK_TYPE_BGUSER, 1.0f / 6)),
|
||||
/* run */ List.of(),
|
||||
/* pen */ List.of(
|
||||
// 2 of these as TOP, 1 as EJ
|
||||
@@ -809,10 +843,12 @@ public class WorkCountTrackerTest {
|
||||
jobs.addPending(WORK_TYPE_BG, 10);
|
||||
|
||||
final int totalMax = 6;
|
||||
final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 1));
|
||||
final List<Pair<Integer, Integer>> maxLimits = List.of(Pair.create(WORK_TYPE_BG, 5));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 1.0f / totalMax));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 5.0f / totalMax));
|
||||
|
||||
recount(jobs, totalMax, minLimits, maxLimits);
|
||||
recount(jobs, totalMax, minLimitRatios, maxLimitRatios);
|
||||
|
||||
startPendingJobs(jobs);
|
||||
|
||||
@@ -887,11 +923,12 @@ public class WorkCountTrackerTest {
|
||||
jobs.addPending(WORK_TYPE_BG, 10); // c
|
||||
|
||||
final int totalMax = 8;
|
||||
final List<Pair<Integer, Integer>> minLimits =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 1), Pair.create(WORK_TYPE_BG, 1));
|
||||
final List<Pair<Integer, Integer>> maxLimits = List.of(Pair.create(WORK_TYPE_BG, 5));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 1.0f / 8), Pair.create(WORK_TYPE_BG, 1.0f / 8));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 5.0f / 8));
|
||||
|
||||
recount(jobs, totalMax, minLimits, maxLimits);
|
||||
recount(jobs, totalMax, minLimitRatios, maxLimitRatios);
|
||||
|
||||
assertThat(jobs.pending.get(WORK_TYPE_TOP)).isEqualTo(11);
|
||||
assertThat(jobs.pending.get(WORK_TYPE_EJ)).isEqualTo(5);
|
||||
@@ -966,11 +1003,12 @@ public class WorkCountTrackerTest {
|
||||
}
|
||||
|
||||
final int totalMax = 8;
|
||||
final List<Pair<Integer, Integer>> minLimits =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 1), Pair.create(WORK_TYPE_BG, 1));
|
||||
final List<Pair<Integer, Integer>> maxLimits = List.of(Pair.create(WORK_TYPE_BG, 5));
|
||||
final List<Pair<Integer, Float>> minLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_EJ, 1.0f / 8), Pair.create(WORK_TYPE_BG, 1.0f / 8));
|
||||
final List<Pair<Integer, Float>> maxLimitRatios =
|
||||
List.of(Pair.create(WORK_TYPE_BG, 5.0f / 8));
|
||||
|
||||
recount(jobs, totalMax, minLimits, maxLimits);
|
||||
recount(jobs, totalMax, minLimitRatios, maxLimitRatios);
|
||||
|
||||
assertThat(jobs.pending.get(WORK_TYPE_TOP)).isEqualTo(11);
|
||||
assertThat(jobs.pending.get(WORK_TYPE_EJ)).isEqualTo(10);
|
||||
|
||||
@@ -45,23 +45,26 @@ import java.util.List;
|
||||
@SmallTest
|
||||
public class WorkTypeConfigTest {
|
||||
private static final String KEY_MAX_TOTAL = "concurrency_max_total_test";
|
||||
private static final String KEY_MAX_TOP = "concurrency_max_top_test";
|
||||
private static final String KEY_MAX_FGS = "concurrency_max_fgs_test";
|
||||
private static final String KEY_MAX_EJ = "concurrency_max_ej_test";
|
||||
private static final String KEY_MAX_BG = "concurrency_max_bg_test";
|
||||
private static final String KEY_MAX_BGUSER_IMPORTANT = "concurrency_max_bguser_important_test";
|
||||
private static final String KEY_MAX_BGUSER = "concurrency_max_bguser_test";
|
||||
private static final String KEY_MIN_TOP = "concurrency_min_top_test";
|
||||
private static final String KEY_MIN_FGS = "concurrency_min_fgs_test";
|
||||
private static final String KEY_MIN_EJ = "concurrency_min_ej_test";
|
||||
private static final String KEY_MIN_BG = "concurrency_min_bg_test";
|
||||
private static final String KEY_MIN_BGUSER_IMPORTANT = "concurrency_min_bguser_important_test";
|
||||
private static final String KEY_MIN_BGUSER = "concurrency_min_bguser_test";
|
||||
private static final String KEY_MAX_RATIO_TOP = "concurrency_max_ratio_top_test";
|
||||
private static final String KEY_MAX_RATIO_FGS = "concurrency_max_ratio_fgs_test";
|
||||
private static final String KEY_MAX_RATIO_EJ = "concurrency_max_ratio_ej_test";
|
||||
private static final String KEY_MAX_RATIO_BG = "concurrency_max_ratio_bg_test";
|
||||
private static final String KEY_MAX_RATIO_BGUSER_IMPORTANT =
|
||||
"concurrency_max_ratio_bguser_important_test";
|
||||
private static final String KEY_MAX_RATIO_BGUSER = "concurrency_max_ratio_bguser_test";
|
||||
private static final String KEY_MIN_RATIO_TOP = "concurrency_min_ratio_top_test";
|
||||
private static final String KEY_MIN_RATIO_FGS = "concurrency_min_ratio_fgs_test";
|
||||
private static final String KEY_MIN_RATIO_EJ = "concurrency_min_ratio_ej_test";
|
||||
private static final String KEY_MIN_RATIO_BG = "concurrency_min_ratio_bg_test";
|
||||
private static final String KEY_MIN_RATIO_BGUSER_IMPORTANT =
|
||||
"concurrency_min_ratio_bguser_important_test";
|
||||
private static final String KEY_MIN_RATIO_BGUSER = "concurrency_min_ratio_bguser_test";
|
||||
|
||||
private void check(@Nullable DeviceConfig.Properties config,
|
||||
int defaultLimit,
|
||||
int defaultTotal,
|
||||
@NonNull List<Pair<Integer, Integer>> defaultMin,
|
||||
@NonNull List<Pair<Integer, Integer>> defaultMax,
|
||||
@NonNull List<Pair<Integer, Float>> defaultMinRatios,
|
||||
@NonNull List<Pair<Integer, Float>> defaultMaxRatios,
|
||||
boolean expectedValid, int expectedTotal,
|
||||
@NonNull List<Pair<Integer, Integer>> expectedMinLimits,
|
||||
@NonNull List<Pair<Integer, Integer>> expectedMaxLimits) throws Exception {
|
||||
@@ -69,7 +72,7 @@ public class WorkTypeConfigTest {
|
||||
final WorkTypeConfig counts;
|
||||
try {
|
||||
counts = new WorkTypeConfig("test",
|
||||
defaultTotal, defaultMin, defaultMax);
|
||||
defaultLimit, defaultTotal, defaultMinRatios, defaultMaxRatios);
|
||||
if (!expectedValid) {
|
||||
fail("Invalid config successfully created");
|
||||
return;
|
||||
@@ -84,7 +87,7 @@ public class WorkTypeConfigTest {
|
||||
}
|
||||
|
||||
if (config != null) {
|
||||
counts.update(config);
|
||||
counts.update(config, defaultLimit);
|
||||
}
|
||||
|
||||
assertEquals(expectedTotal, counts.getMaxTotal());
|
||||
@@ -101,7 +104,7 @@ public class WorkTypeConfigTest {
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
// Tests with various combinations.
|
||||
check(null, /*default*/ 13,
|
||||
check(null, /* limit */ 16, /*default*/ 13,
|
||||
/* min */ List.of(),
|
||||
/* max */ List.of(),
|
||||
/*expected*/ true, 13,
|
||||
@@ -109,111 +112,141 @@ public class WorkTypeConfigTest {
|
||||
Pair.create(WORK_TYPE_BG, 0), Pair.create(WORK_TYPE_BGUSER, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 13), Pair.create(WORK_TYPE_EJ, 13),
|
||||
Pair.create(WORK_TYPE_BG, 13), Pair.create(WORK_TYPE_BGUSER, 13)));
|
||||
check(null, /*default*/ 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1)),
|
||||
check(null, /* limit */ 16, /*default*/ 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, .8f), Pair.create(WORK_TYPE_BG, 0f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, .2f)),
|
||||
/*expected*/ true, 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5), Pair.create(WORK_TYPE_BG, 1)));
|
||||
check(null, /*default*/ 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 5),
|
||||
Pair.create(WORK_TYPE_BG, 0), Pair.create(WORK_TYPE_BGUSER, 0)),
|
||||
check(null, /* limit */ 16, /*default*/ 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1f),
|
||||
Pair.create(WORK_TYPE_BG, 0f), Pair.create(WORK_TYPE_BGUSER, 0f)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 0), Pair.create(WORK_TYPE_BGUSER, 1)),
|
||||
/*expected*/ true, 5,
|
||||
Pair.create(WORK_TYPE_BG, 0f), Pair.create(WORK_TYPE_BGUSER, .2f)),
|
||||
/*expected*/ false, 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 5),
|
||||
Pair.create(WORK_TYPE_BG, 0), Pair.create(WORK_TYPE_BGUSER, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5),
|
||||
Pair.create(WORK_TYPE_BG, 1), Pair.create(WORK_TYPE_BGUSER, 1)));
|
||||
check(null, /*default*/ 0,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 5), Pair.create(WORK_TYPE_BG, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 0)),
|
||||
/*expected*/ false, 1,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 1)));
|
||||
check(null, /*default*/ -1,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, -1)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, -1)),
|
||||
/*expected*/ false, 1,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 1)));
|
||||
check(null, /*default*/ 5,
|
||||
/* min */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 0)),
|
||||
check(null, /* limit */ 16, /*default*/ 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, .99f),
|
||||
Pair.create(WORK_TYPE_BG, 0f), Pair.create(WORK_TYPE_BGUSER, 0f)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 5)),
|
||||
Pair.create(WORK_TYPE_BG, .01f), Pair.create(WORK_TYPE_BGUSER, .2f)),
|
||||
/*expected*/ true, 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 4),
|
||||
Pair.create(WORK_TYPE_BG, 0), Pair.create(WORK_TYPE_BGUSER, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5),
|
||||
Pair.create(WORK_TYPE_BG, 1), Pair.create(WORK_TYPE_BGUSER, 1)));
|
||||
check(null, /* limit */ 16, /*default*/ 0,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1f), Pair.create(WORK_TYPE_BG, 0f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 0f)),
|
||||
/*expected*/ false, 1,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 1)));
|
||||
check(null, /* limit */ 16, /*default*/ -1,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, -1f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, -1f)),
|
||||
/*expected*/ false, 1,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 1)));
|
||||
check(null, /* limit */ 16, /*default*/ 5,
|
||||
/* min */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 0f)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1f)),
|
||||
/*expected*/ false, 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
|
||||
Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5),
|
||||
Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 5)));
|
||||
check(null, /* limit */ 16, /*default*/ 5,
|
||||
/* min */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, .99f), Pair.create(WORK_TYPE_BGUSER, 0f)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1f)),
|
||||
/*expected*/ true, 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
|
||||
Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5),
|
||||
Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 5)));
|
||||
check(null, /*default*/ 6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
|
||||
Pair.create(WORK_TYPE_BG, 6), Pair.create(WORK_TYPE_BGUSER, 2)),
|
||||
check(null, /* limit */ 16, /*default*/ 6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1.0f / 6),
|
||||
Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1.0f / 3)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 1)),
|
||||
Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1.0f / 6)),
|
||||
/*expected*/ false, 6,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
|
||||
Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 6),
|
||||
Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 1)));
|
||||
check(null, /*default*/ 4,
|
||||
check(null, /* limit */ 16, /*default*/ 4,
|
||||
/* min */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 6), Pair.create(WORK_TYPE_BGUSER, 6)),
|
||||
Pair.create(WORK_TYPE_BG, 1.5f), Pair.create(WORK_TYPE_BGUSER, 1.5f)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 5)),
|
||||
Pair.create(WORK_TYPE_BG, 1.25f), Pair.create(WORK_TYPE_BGUSER, 1.25f)),
|
||||
/*expected*/ false, 4,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
|
||||
Pair.create(WORK_TYPE_BG, 3), Pair.create(WORK_TYPE_BGUSER, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 4),
|
||||
Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 4)));
|
||||
check(null, /*default*/ 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1)),
|
||||
check(null, /* limit */ 16, /*default*/ 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, .8f), Pair.create(WORK_TYPE_BG, .2f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, .2f)),
|
||||
/*expected*/ true, 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5), Pair.create(WORK_TYPE_BG, 1)));
|
||||
check(null, /*default*/ 10,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_EJ, 3),
|
||||
Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1)),
|
||||
check(null, /* limit */ 16, /*default*/ 10,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, .4f), Pair.create(WORK_TYPE_EJ, .3f),
|
||||
Pair.create(WORK_TYPE_BG, .1f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, .1f)),
|
||||
/*expected*/ true, 10,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_EJ, 3),
|
||||
Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 1)));
|
||||
check(null, /*default*/ 10,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 3), Pair.create(WORK_TYPE_FGS, 2),
|
||||
Pair.create(WORK_TYPE_EJ, 1), Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_FGS, 3)),
|
||||
check(null, /* limit */ 16, /*default*/ 10,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, .3f), Pair.create(WORK_TYPE_FGS, .2f),
|
||||
Pair.create(WORK_TYPE_EJ, .1f), Pair.create(WORK_TYPE_BG, .1f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_FGS, .3f)),
|
||||
/*expected*/ true, 10,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 3), Pair.create(WORK_TYPE_FGS, 2),
|
||||
Pair.create(WORK_TYPE_EJ, 1), Pair.create(WORK_TYPE_BG, 1)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_FGS, 3)));
|
||||
check(null, /*default*/ 15,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 15)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 15)),
|
||||
check(null, /* limit */ 16, /*default*/ 15,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .95f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
|
||||
/*expected*/ true, 15,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 14)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 15), Pair.create(WORK_TYPE_BG, 15)));
|
||||
check(null, /*default*/ 16,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 16)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 16)),
|
||||
check(null, /* limit */ 16, /*default*/ 16,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
|
||||
/*expected*/ true, 16,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 15)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_BG, 16)));
|
||||
check(null, /*default*/ 20,
|
||||
check(null, /* limit */ 16, /*default*/ 20,
|
||||
/* min */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 20), Pair.create(WORK_TYPE_BGUSER, 10)),
|
||||
Pair.create(WORK_TYPE_BG, .99f), Pair.create(WORK_TYPE_BGUSER, .5f)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 20), Pair.create(WORK_TYPE_BGUSER, 20)),
|
||||
Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1f)),
|
||||
/*expected*/ false, 16,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
|
||||
Pair.create(WORK_TYPE_BG, 15), Pair.create(WORK_TYPE_BGUSER, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 16),
|
||||
Pair.create(WORK_TYPE_BG, 16), Pair.create(WORK_TYPE_BGUSER, 16)));
|
||||
check(null, /*default*/ 20,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 16)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 16)),
|
||||
check(null, /* limit */ 76, /*default*/ 80,
|
||||
/* min */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, .98f), Pair.create(WORK_TYPE_BGUSER, .9f)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1f)),
|
||||
/*expected*/ false, 64,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
|
||||
Pair.create(WORK_TYPE_BG, 63), Pair.create(WORK_TYPE_BGUSER, 0)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 64),
|
||||
Pair.create(WORK_TYPE_BG, 64), Pair.create(WORK_TYPE_BGUSER, 64)));
|
||||
check(null, /* limit */ 16, /*default*/ 20,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
|
||||
/*expected*/ true, 16,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 15)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_BG, 16)));
|
||||
@@ -221,94 +254,101 @@ public class WorkTypeConfigTest {
|
||||
// Test for overriding with a setting string.
|
||||
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
|
||||
.setInt(KEY_MAX_TOTAL, 5)
|
||||
.setInt(KEY_MAX_BG, 4)
|
||||
.setInt(KEY_MIN_BG, 3)
|
||||
.setFloat(KEY_MAX_RATIO_BG, .8f)
|
||||
.setFloat(KEY_MIN_RATIO_BG, .6f)
|
||||
.build(),
|
||||
/* limit */ 16,
|
||||
/*default*/ 9,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
|
||||
/* max */ List.of(
|
||||
Pair.create(WORK_TYPE_BG, 9), Pair.create(WORK_TYPE_BGUSER, 2)),
|
||||
Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, .4f)),
|
||||
/*expected*/ true, 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 3)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5),
|
||||
Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2)));
|
||||
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
|
||||
.setInt(KEY_MAX_TOTAL, 5).build(),
|
||||
/* limit */ 16,
|
||||
/*default*/ 9,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
|
||||
/*expected*/ true, 5,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 4)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5), Pair.create(WORK_TYPE_BG, 5)));
|
||||
|
||||
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
|
||||
.setInt(KEY_MAX_BG, 4).build(),
|
||||
.setFloat(KEY_MAX_RATIO_BG, 4.0f / 9).build(),
|
||||
/* limit */ 16,
|
||||
/*default*/ 9,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
|
||||
/*expected*/ true, 9,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 4)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 9), Pair.create(WORK_TYPE_BG, 4)));
|
||||
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
|
||||
.setInt(KEY_MIN_BG, 3).build(),
|
||||
.setFloat(KEY_MIN_RATIO_BG, 1.0f / 3).build(),
|
||||
/* limit */ 16,
|
||||
/*default*/ 9,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
|
||||
/*expected*/ true, 9,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 3)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 9), Pair.create(WORK_TYPE_BG, 9)));
|
||||
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
|
||||
.setInt(KEY_MAX_TOTAL, 20)
|
||||
.setInt(KEY_MAX_EJ, 5)
|
||||
.setInt(KEY_MIN_EJ, 2)
|
||||
.setInt(KEY_MAX_BG, 16)
|
||||
.setInt(KEY_MIN_BG, 8)
|
||||
.setFloat(KEY_MAX_RATIO_EJ, .25f)
|
||||
.setFloat(KEY_MIN_RATIO_EJ, .1f)
|
||||
.setFloat(KEY_MAX_RATIO_BG, .8f)
|
||||
.setFloat(KEY_MIN_RATIO_BG, .4f)
|
||||
.build(),
|
||||
/* limit */ 16,
|
||||
/*default*/ 9,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
|
||||
/*expected*/ true, 16,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_EJ, 2),
|
||||
Pair.create(WORK_TYPE_BG, 8)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_EJ, 1),
|
||||
Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* max */
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_EJ, 5),
|
||||
Pair.create(WORK_TYPE_BG, 16)));
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_EJ, 4),
|
||||
Pair.create(WORK_TYPE_BG, 12)));
|
||||
|
||||
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
|
||||
.setInt(KEY_MAX_TOTAL, 20)
|
||||
.setInt(KEY_MAX_BG, 20)
|
||||
.setInt(KEY_MIN_BG, 8)
|
||||
.setFloat(KEY_MAX_RATIO_BG, 1f)
|
||||
.setFloat(KEY_MIN_RATIO_BG, .4f)
|
||||
.build(),
|
||||
/* limit */ 16,
|
||||
/*default*/ 9,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
|
||||
/*expected*/ true, 16,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 8)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 6)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_BG, 16)));
|
||||
|
||||
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
|
||||
.setInt(KEY_MAX_TOTAL, 16)
|
||||
.setInt(KEY_MAX_TOP, 16)
|
||||
.setInt(KEY_MIN_TOP, 1)
|
||||
.setInt(KEY_MAX_FGS, 15)
|
||||
.setInt(KEY_MIN_FGS, 2)
|
||||
.setInt(KEY_MAX_EJ, 14)
|
||||
.setInt(KEY_MIN_EJ, 3)
|
||||
.setInt(KEY_MAX_BG, 13)
|
||||
.setInt(KEY_MIN_BG, 4)
|
||||
.setInt(KEY_MAX_BGUSER_IMPORTANT, 12)
|
||||
.setInt(KEY_MIN_BGUSER_IMPORTANT, 5)
|
||||
.setInt(KEY_MAX_BGUSER, 11)
|
||||
.setInt(KEY_MIN_BGUSER, 6)
|
||||
.setFloat(KEY_MAX_RATIO_TOP, 1f)
|
||||
.setFloat(KEY_MIN_RATIO_TOP, 1.0f / 16)
|
||||
.setFloat(KEY_MAX_RATIO_FGS, 15.0f / 16)
|
||||
.setFloat(KEY_MIN_RATIO_FGS, 2.0f / 16)
|
||||
.setFloat(KEY_MAX_RATIO_EJ, 14.0f / 16)
|
||||
.setFloat(KEY_MIN_RATIO_EJ, 3.0f / 16)
|
||||
.setFloat(KEY_MAX_RATIO_BG, 13.0f / 16)
|
||||
.setFloat(KEY_MIN_RATIO_BG, 3.0f / 16)
|
||||
.setFloat(KEY_MAX_RATIO_BGUSER_IMPORTANT, 12.0f / 16)
|
||||
.setFloat(KEY_MIN_RATIO_BGUSER_IMPORTANT, 2.0f / 16)
|
||||
.setFloat(KEY_MAX_RATIO_BGUSER, 11.0f / 16)
|
||||
.setFloat(KEY_MIN_RATIO_BGUSER, 2.0f / 16)
|
||||
.build(),
|
||||
/* limit */ 16,
|
||||
/*default*/ 9,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
|
||||
/* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
|
||||
/*expected*/ true, 16,
|
||||
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_FGS, 2),
|
||||
Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 4),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 5),
|
||||
Pair.create(WORK_TYPE_BGUSER, 6)),
|
||||
Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 3),
|
||||
Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 2),
|
||||
Pair.create(WORK_TYPE_BGUSER, 2)),
|
||||
/* max */
|
||||
List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_FGS, 15),
|
||||
Pair.create(WORK_TYPE_EJ, 14), Pair.create(WORK_TYPE_BG, 13),
|
||||
|
||||
Reference in New Issue
Block a user