Skip to content

Commit 4deaf60

Browse files
committed
Optimized by lookup maps
1 parent e2cccb8 commit 4deaf60

File tree

2 files changed

+50
-56
lines changed

2 files changed

+50
-56
lines changed

optimizely/optimizely.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,6 @@ def get_forced_variation(self, experiment_key, user_id):
735735
forced_variation = self.decision_service.get_forced_variation(project_config, experiment_key, user_id)
736736
return forced_variation.key if forced_variation else None
737737

738-
739738
def get_optimizely_config(self):
740739
if not self.is_valid:
741740
self.logger.error(enums.Errors.INVALID_OPTIMIZELY.format('get_optimizely_config'))
@@ -746,4 +745,4 @@ def get_optimizely_config(self):
746745
self.logger.error(enums.Errors.INVALID_PROJECT_CONFIG.format('get_optimizely_config'))
747746
return None
748747

749-
return OptimizelyConfigBuilder(project_config).get_optimizely_config()
748+
return OptimizelyConfigBuilder(project_config).build()

optimizely/optimizely_config.py

Lines changed: 49 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,38 @@
1111
# See the License for the specific language governing permissions and
1212
# limitations under the License.
1313

14-
import json
14+
import copy
15+
1516

1617
class OptimizelyConfig(object):
1718
def __init__(self, revision, experiments_map, features_map):
1819
self.revision = revision
19-
self.experimentsMap = experiments_map
20-
self.featuresMap = features_map
20+
self.experiments_map = experiments_map
21+
self.features_map = features_map
22+
2123

2224
class OptimizelyExperiment(object):
2325
def __init__(self, id, key, variations_map):
2426
self.id = id
2527
self.key = key
26-
self.variationsMap = variations_map
28+
self.variations_map = variations_map
29+
2730

2831
class OptimizelyFeature(object):
2932
def __init__(self, id, key, experiments_map, variables_map):
3033
self.id = id
3134
self.key = key
32-
self.experimentsMap = experiments_map
33-
self.variablesMap = variables_map
35+
self.experiments_map = experiments_map
36+
self.variables_map = variables_map
37+
3438

3539
class OptimizelyVariation(object):
3640
def __init__(self, id, key, feature_enabled, variables_map):
3741
self.id = id
3842
self.key = key
39-
self.featureEnabled = feature_enabled
40-
self.variablesMap = variables_map
43+
self.feature_enabled = feature_enabled
44+
self.variables_map = variables_map
45+
4146

4247
class OptimizelyVariable(object):
4348
def __init__(self, id, key, type, value):
@@ -55,53 +60,51 @@ def __init__(self, project_config):
5560
self.groups = project_config.groups
5661
self.revision = project_config.revision
5762

58-
def get_optimizely_config(self):
59-
experiments_map = self._get_experiments_map()
60-
features_map = self._get_features_map(experiments_map)
63+
def build(self):
64+
self._create_lookup_maps()
6165

62-
return OptimizelyConfig(self.revision, experiments_map, features_map)
66+
experiments_key_map, experiments_id_map = self._get_experiments_maps()
67+
features_map = self._get_features_map(experiments_id_map)
6368

64-
def _get_feature_variable_by_id(self, variable_id, feature_flag):
65-
for variable in feature_flag.get('variables', []):
66-
if variable_id == variable['id']:
67-
return variable
68-
return None
69+
return OptimizelyConfig(self.revision, experiments_key_map, features_map)
6970

70-
def _get_featureflag_by_experiment_id(self, experiment_id):
71+
def _create_lookup_maps(self):
72+
self.exp_id_to_feature_map = {}
7173
for feature in self.feature_flags:
7274
for id in feature['experimentIds']:
73-
if id == experiment_id:
74-
return feature
75-
return None
75+
self.exp_id_to_feature_map[id] = feature
7676

77-
def _get_experiment_by_id(self, experiment_id, experiments_map):
78-
for experiment in experiments_map.values():
79-
if experiment.id == experiment_id:
80-
return experiment
77+
self.feature_key_variable_key_to_variable_map = {}
78+
self.feature_key_variable_id_to_variable_map = {}
79+
for feature in self.feature_flags:
80+
variables_key_map = {}
81+
variables_id_map = {}
82+
for variable in feature.get('variables', []):
83+
opt_variable = OptimizelyVariable(
84+
variable['id'], variable['key'], variable['type'], variable['defaultValue']
85+
)
86+
variables_key_map[variable['key']] = opt_variable
87+
variables_id_map[variable['id']] = opt_variable
8188

82-
return None
89+
self.feature_key_variable_key_to_variable_map[feature['key']] = variables_key_map
90+
self.feature_key_variable_id_to_variable_map[feature['key']] = variables_id_map
8391

8492
def _get_variables_map(self, variation, experiment):
85-
feature_flag = self._get_featureflag_by_experiment_id(experiment['id'])
93+
feature_flag = self.exp_id_to_feature_map.get(experiment['id'], None)
8694
if feature_flag is None:
8795
return {}
8896

8997
# set default variables for each variation
9098
variables_map = {}
91-
for variable in feature_flag.get('variables', []):
92-
opt_variable = OptimizelyVariable(
93-
variable['id'], variable['key'], variable['type'], variable['defaultValue']
94-
)
95-
variables_map[variable['key']] = opt_variable
96-
99+
variables_map = copy.deepcopy(self.feature_key_variable_key_to_variable_map[feature_flag['key']])
97100

98101
# set variation specific variable value if any
99102
if variation.get('featureEnabled', None):
100103
for variable in variation.get('variables', []):
101-
feature_variable = self._get_feature_variable_by_id(variable['id'], feature_flag)
102-
variables_map[feature_variable['key']].value = variable['value']
104+
feature_variable = self.feature_key_variable_id_to_variable_map[feature_flag['key']][variable['id']]
105+
variables_map[feature_variable.key].value = variable['value']
103106

104-
return variables_map
107+
return variables_map
105108

106109
def _get_variations_map(self, experiment):
107110
variations_map = {}
@@ -126,44 +129,36 @@ def _get_all_experiments(self):
126129

127130
return experiments
128131

129-
def _get_experiments_map(self):
130-
experiments_map = {}
132+
def _get_experiments_maps(self):
133+
experiments_key_map = {}
134+
experiments_id_map = {}
131135
all_experiments = self._get_all_experiments()
132-
136+
133137
for exp in all_experiments:
134138
optly_exp = OptimizelyExperiment(
135139
exp['id'], exp['key'], self._get_variations_map(exp)
136140
)
137141

138-
experiments_map[exp['key']] = optly_exp
142+
experiments_key_map[exp['key']] = optly_exp
143+
experiments_id_map[exp['id']] = optly_exp
139144

140-
return experiments_map
145+
return experiments_key_map, experiments_id_map
141146

142-
def _get_features_map(self, experiments_map):
147+
def _get_features_map(self, experiments_id_map):
143148
features_map = {}
144149

145150
for feature in self.feature_flags:
146151
exp_map = {}
147152
for experiment_id in feature.get('experimentIds', []):
148-
optly_exp = self._get_experiment_by_id(experiment_id, experiments_map)
153+
optly_exp = experiments_id_map[experiment_id]
149154
exp_map[optly_exp.key] = optly_exp
150155

151-
152-
153-
variables_map = {}
154-
for variable in feature['variables']:
155-
optly_variable = OptimizelyVariable(
156-
variable['id'], variable['key'], variable['type'], variable['defaultValue']
157-
)
158-
159-
variables_map[variable['key']] = optly_variable
160-
156+
variables_map = self.feature_key_variable_key_to_variable_map[feature['key']]
161157

162158
optly_feature = OptimizelyFeature(
163159
feature['id'], feature['key'], exp_map, variables_map
164160
)
165161

166162
features_map[feature['key']] = optly_feature
167163

168-
169164
return features_map

0 commit comments

Comments
 (0)