hypertune/
split.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Map;
5use serde_json::Number;
6use serde_json::Value;
7
8use crate::expression::Logs;
9
10pub type SplitMap = HashMap<String, Split>;
11
12#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
13#[serde(rename_all = "camelCase")]
14pub struct Split {
15    pub id: String,
16    pub r#type: SplitType,
17    pub dimensions: HashMap<String, Dimension>,
18}
19
20#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
21pub enum SplitType {
22    #[serde(rename = "test")]
23    Test,
24
25    #[serde(rename = "ml")]
26    ML,
27}
28
29#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
30#[serde(tag = "type", rename_all = "camelCase")]
31pub enum Dimension {
32    Discrete(DiscreteDimension),
33    Continuous(ContinuousDimension),
34}
35
36impl Dimension {
37    pub fn get_id(&self) -> &str {
38        match self {
39            Dimension::Discrete(d) => &d.id,
40            Dimension::Continuous(d) => &d.id,
41        }
42    }
43}
44
45#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
46#[serde(rename_all = "camelCase")]
47pub struct DiscreteDimension {
48    pub id: String,
49    split_id: String,
50    index: u64,
51    name: String,
52    pub arms: HashMap<String, Arm>,
53}
54
55#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
56#[serde(rename_all = "camelCase")]
57pub struct ContinuousDimension {
58    pub id: String,
59    split_id: String,
60    index: u64,
61    name: String,
62}
63
64#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
65#[serde(rename_all = "camelCase")]
66pub struct Arm {
67    pub id: String,
68    dimension_id: String,
69    pub index: u64,
70    name: String,
71    pub allocation: Number,
72}
73
74#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
75#[serde(rename_all = "camelCase")]
76pub struct CommitConfig {
77    pub split_config: HashMap<String, SplitConfig>,
78}
79
80impl CommitConfig {
81    pub fn new() -> Self {
82        Self {
83            split_config: HashMap::new(),
84        }
85    }
86}
87
88#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
89#[serde(tag = "type")]
90pub enum SplitConfig {
91    EpsilonGreedyConfig(EpsilonGreedyConfig),
92    PersonalizationSplitConfig(PersonalizationSplitConfig),
93}
94
95#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
96#[serde(rename_all = "camelCase")]
97pub struct EpsilonGreedyConfig {
98    pub epsilon: Number,
99    pub best_assignment: HashMap<String, SplitAssignmentEntry>,
100}
101
102#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
103pub struct PersonalizationSplitConfig {
104    pub epsilon: Number,
105    pub logic: HashMap<String, PersonalizationSplitLogicDimension>,
106}
107
108#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
109#[serde(rename_all = "camelCase")]
110pub struct PersonalizationSplitLogicDimension {
111    pub rules: Vec<PersonalSplitLogicDimensionRule>,
112    pub default_arm_id: String,
113}
114
115#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
116#[serde(rename_all = "camelCase")]
117pub struct PersonalSplitLogicDimensionRule {
118    pub feature_values_path: Vec<String>,
119    pub feature_value: Value,
120    pub arm_id: String,
121}
122
123#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
124#[serde(rename_all = "camelCase")]
125pub struct AssignmentCacheValue {
126    pub assignment: HashMap<String, SplitAssignmentEntry>,
127    pub event_object_type_name: Option<String>,
128    pub event_payload: Option<Map<String, Value>>,
129    pub event_payload_logs: Option<Logs>,
130}
131
132#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone, Hash)]
133#[serde(rename_all = "camelCase")]
134pub struct AssignmentCacheKey {
135    pub split_id: String,
136    pub unit_id: String,
137}
138
139pub type AssignmentCache = HashMap<AssignmentCacheKey, AssignmentCacheValue>;
140
141#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
142#[serde(rename_all = "camelCase", tag = "type")]
143pub enum SplitAssignmentEntry {
144    #[serde(rename_all = "camelCase")]
145    Discrete {
146        arm_id: String,
147    },
148
149    Continuous {
150        value: Number,
151    },
152}