Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions rl.install
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function rl_install() {
'experiment_unique' => ['experiment_uuid'],
],
'indexes' => [
'experiment_uuid' => ['experiment_uuid'],
'experiment_updated' => ['experiment_uuid', 'updated'],
],
];

Expand Down Expand Up @@ -123,7 +123,7 @@ function rl_install() {
'experiment_arm' => ['experiment_uuid', 'arm_id'],
],
'indexes' => [
'experiment_uuid' => ['experiment_uuid'],
'covering_time_window' => ['experiment_uuid', 'updated', 'arm_id', 'turns', 'rewards', 'created'],
],
];

Expand Down Expand Up @@ -249,7 +249,7 @@ function rl_schema() {
'experiment_unique' => ['experiment_uuid'],
],
'indexes' => [
'experiment_uuid' => ['experiment_uuid'],
'experiment_updated' => ['experiment_uuid', 'updated'],
],
];

Expand Down Expand Up @@ -307,7 +307,7 @@ function rl_schema() {
'experiment_arm' => ['experiment_uuid', 'arm_id'],
],
'indexes' => [
'experiment_uuid' => ['experiment_uuid'],
'covering_time_window' => ['experiment_uuid', 'updated', 'arm_id', 'turns', 'rewards', 'created'],
],
];

Expand Down
13 changes: 12 additions & 1 deletion src/Service/ExperimentManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,18 @@ public function getTotalTurns($experiment_uuid) {
* {@inheritdoc}
*/
public function getThompsonScores($experiment_uuid) {
$arms_data = $this->getAllArmsData($experiment_uuid);
return $this->getThompsonScoresWithWindow($experiment_uuid, NULL);
}

/**
* {@inheritdoc}
*/
public function getThompsonScoresWithWindow($experiment_uuid, $time_window_seconds = NULL) {
$arms_data = $this->storage->getAllArmsDataWithWindow($experiment_uuid, $time_window_seconds);

if (empty($arms_data)) {
return [];
}

return $this->tsCalculator->calculateThompsonScores($arms_data);
}
Expand Down
13 changes: 13 additions & 0 deletions src/Service/ExperimentManagerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,17 @@ public function getTotalTurns($experiment_uuid);
*/
public function getThompsonScores($experiment_uuid);

/**
* Gets Thompson Sampling scores for all arms with seconds-based time window.
*
* @param string $experiment_uuid
* The experiment UUID.
* @param int|null $time_window_seconds
* Optional time window in seconds. Only considers arms active within this timeframe.
*
* @return array
* Array of Thompson Sampling scores keyed by arm_id.
*/
public function getThompsonScoresWithWindow($experiment_uuid, $time_window_seconds = NULL);

}
30 changes: 20 additions & 10 deletions src/Storage/ExperimentDataStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,11 @@ public function getArmData($experiment_uuid, $arm_id) {
* {@inheritdoc}
*/
public function getAllArmsData($experiment_uuid, $time_window_days = NULL) {
$query = $this->database->select('rl_arm_data', 'ad')
->fields('ad', ['arm_id', 'turns', 'rewards', 'created', 'updated'])
->condition('experiment_uuid', $experiment_uuid);

// Apply time window filter if specified.
if ($time_window_days !== NULL && $time_window_days > 0) {
$cutoff_timestamp = \Drupal::time()->getRequestTime() - ($time_window_days * 86400);
$query->condition('updated', $cutoff_timestamp, '>=');
$time_window_seconds = NULL;
if ($time_window_days && $time_window_days > 0) {
$time_window_seconds = $time_window_days * 86400;
}

return $query->execute()->fetchAllAssoc('arm_id');
return $this->getAllArmsDataWithWindow($experiment_uuid, $time_window_seconds);
}

/**
Expand Down Expand Up @@ -149,4 +143,20 @@ public function getTotalTurns($experiment_uuid, $time_window_days = NULL) {
return $result ? (int) $result : 0;
}

/**
* {@inheritdoc}
*/
public function getAllArmsDataWithWindow($experiment_uuid, $time_window_seconds = NULL) {
$query = $this->database->select('rl_arm_data', 'ad')
->fields('ad', ['arm_id', 'turns', 'rewards', 'created', 'updated'])
->condition('experiment_uuid', $experiment_uuid);

if ($time_window_seconds && $time_window_seconds > 0) {
$cutoff_timestamp = \Drupal::time()->getRequestTime() - $time_window_seconds;
$query->condition('updated', $cutoff_timestamp, '>=');
}

return $query->execute()->fetchAllAssoc('arm_id');
}

}
13 changes: 13 additions & 0 deletions src/Storage/ExperimentDataStorageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,17 @@ public function getAllArmsData($experiment_uuid);
*/
public function getTotalTurns($experiment_uuid);

/**
* Gets data for all arms in an experiment with seconds-based time window.
*
* @param string $experiment_uuid
* The experiment UUID.
* @param int|null $time_window_seconds
* Optional time window in seconds. Only returns arms active within this timeframe.
*
* @return array
* Array of arm data objects keyed by arm_id.
*/
public function getAllArmsDataWithWindow($experiment_uuid, $time_window_seconds = NULL);

}