diff --git a/community-resources/intellij.idea.community.customization.iml b/community-resources/intellij.idea.community.customization.iml index a73828cc90ad..c1f7e4424e98 100644 --- a/community-resources/intellij.idea.community.customization.iml +++ b/community-resources/intellij.idea.community.customization.iml @@ -26,5 +26,6 @@ + \ No newline at end of file diff --git a/community-resources/resources/META-INF/IdeaPlugin.xml b/community-resources/resources/META-INF/IdeaPlugin.xml index 4efc3c962494..70fbbb494bf1 100644 --- a/community-resources/resources/META-INF/IdeaPlugin.xml +++ b/community-resources/resources/META-INF/IdeaPlugin.xml @@ -16,6 +16,7 @@ + diff --git a/platform/experiment/intellij.platform.experiment.iml b/platform/experiment/intellij.platform.experiment.iml new file mode 100644 index 000000000000..bdb38f7d8f4e --- /dev/null +++ b/platform/experiment/intellij.platform.experiment.iml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platform/experiment/resources/intellij.platform.experiment.xml b/platform/experiment/resources/intellij.platform.experiment.xml new file mode 100644 index 000000000000..81058a8fd026 --- /dev/null +++ b/platform/experiment/resources/intellij.platform.experiment.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/platform/experiment/src/com/intellij/platform/experiment/ab/ABExperiment.kt b/platform/experiment/src/com/intellij/platform/experiment/ab/ABExperiment.kt new file mode 100644 index 000000000000..d9671cecf81e --- /dev/null +++ b/platform/experiment/src/com/intellij/platform/experiment/ab/ABExperiment.kt @@ -0,0 +1,69 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.platform.experiment.ab + +import com.intellij.internal.statistic.eventLog.EventLogConfiguration +import com.intellij.openapi.util.registry.Registry +import com.intellij.util.PlatformUtils + +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +abstract class ABExperiment { + + abstract val id: String + + protected abstract val experimentConfig: T + + protected abstract val testRegistryKey: String + + fun isExperimentEnabled(): Boolean { + return getUserGroupKind() == GroupKind.Experimental + } + + fun getUserGroupNumber(): Int { + val testRegistryExperimentGroup = Registry.intValue(testRegistryKey, -1, -1, experimentConfig.totalNumberOfBuckets - 1) + if (testRegistryExperimentGroup >= 0) return testRegistryExperimentGroup + + val bucket = getBucket() + val experimentGroup = bucket % getTotalNumberOfGroups() + return experimentGroup + } + + fun getUserGroupKind(): GroupKind { + val groupNumber = getUserGroupNumber() + return if (isPopularIDE()) { + when (groupNumber) { + in experimentConfig.experimentalGroupNumbersForPopularIde -> GroupKind.Experimental + in experimentConfig.controlGroupNumbersForPopularIde -> GroupKind.Control + else -> GroupKind.Experimental + } + } + else { + when (groupNumber) { + in experimentConfig.experimentalGroupNumbersForRegularIde -> GroupKind.Experimental + in experimentConfig.controlGroupNumbersForRegularIde -> GroupKind.Control + else -> GroupKind.Experimental + } + } + } + + private fun getTotalNumberOfGroups(): Int { + return if (isPopularIDE()) { + experimentConfig.experimentalGroupNumbersForPopularIde.size + experimentConfig.controlGroupNumbersForPopularIde.size + } + else { + experimentConfig.experimentalGroupNumbersForRegularIde.size + experimentConfig.controlGroupNumbersForRegularIde.size + } + } + + private fun getBucket(): Int { + val eventLogConfiguration = EventLogConfiguration.getInstance() + return eventLogConfiguration.bucket % experimentConfig.totalNumberOfBuckets + } + + private fun isPopularIDE() = PlatformUtils.isIdeaUltimate() || PlatformUtils.isPyCharmPro() + + + enum class GroupKind { + Experimental, + Control + } +} \ No newline at end of file diff --git a/platform/experiment/src/com/intellij/platform/experiment/ab/ABExperimentConfigBase.kt b/platform/experiment/src/com/intellij/platform/experiment/ab/ABExperimentConfigBase.kt new file mode 100644 index 000000000000..78557b36712f --- /dev/null +++ b/platform/experiment/src/com/intellij/platform/experiment/ab/ABExperimentConfigBase.kt @@ -0,0 +1,10 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.platform.experiment.ab + +abstract class ABExperimentConfigBase { + open val experimentalGroupNumbersForPopularIde = (0..7).toList() + open val controlGroupNumbersForPopularIde = listOf(8, 9) + open val experimentalGroupNumbersForRegularIde = listOf(0, 1) + open val controlGroupNumbersForRegularIde = listOf(2) + open val totalNumberOfBuckets = 256 +} diff --git a/platform/experiment/src/com/intellij/platform/experiment/demo/DemoABExperiment.kt b/platform/experiment/src/com/intellij/platform/experiment/demo/DemoABExperiment.kt new file mode 100644 index 000000000000..8140da85f99b --- /dev/null +++ b/platform/experiment/src/com/intellij/platform/experiment/demo/DemoABExperiment.kt @@ -0,0 +1,24 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.platform.experiment.demo + +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.components.Service +import com.intellij.openapi.components.service +import com.intellij.platform.experiment.ab.ABExperiment +import com.intellij.platform.experiment.ab.ABExperimentConfigBase + +fun getInstance(): DemoABExperiment { + return ApplicationManager.getApplication().service() +} + + +@Service +class DemoABExperiment : ABExperiment() { + + override val id: String = "demo.ab_experiment" + + override val experimentConfig: ABExperimentConfigBase = object : ABExperimentConfigBase() {} + + override val testRegistryKey: String = "demo.ab_experiment" + +} \ No newline at end of file diff --git a/platform/experiment/src/com/intellij/platform/experiment/demo/DemoABExperimentAction.kt b/platform/experiment/src/com/intellij/platform/experiment/demo/DemoABExperimentAction.kt new file mode 100644 index 000000000000..c37322543bad --- /dev/null +++ b/platform/experiment/src/com/intellij/platform/experiment/demo/DemoABExperimentAction.kt @@ -0,0 +1,13 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.platform.experiment.demo + +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent + +class DemoABExperimentAction : AnAction("Aaaaaaa test") { + override fun actionPerformed(e: AnActionEvent) { + println(getInstance().isExperimentEnabled()) + println(getInstance().getUserGroupKind()) + println(getInstance().getUserGroupNumber()) + } +} \ No newline at end of file