chg: [attribute:restSearch] Improved performance of `includeDecayScore` by a factor of 5

pull/7976/merge
Sami Mokaddem 2024-03-12 11:32:10 +01:00
parent aaf3633cb0
commit ec769c3f27
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
5 changed files with 43 additions and 4 deletions

View File

@ -1944,6 +1944,9 @@ class Attribute extends AppModel
$attribute['Attribute']['data'] = $encodedFile;
}
if ($options['includeDecayScore']) {
if (empty($attribute['Attribute']['to_ids'])) {
continue; // It only makes sense to consider IoCs for the decaying
}
$this->DecayingModel = ClassRegistry::init('DecayingModel');
$include_full_model = isset($options['includeFullModel']) && $options['includeFullModel'] ? 1 : 0;
if (empty($attribute['Attribute']['AttributeTag'])) {

View File

@ -16,6 +16,9 @@ class DecayingModel extends AppModel
)
);
private $modelCache = [];
private $modelCacheForType = [];
private $__registered_model_classes = array(); // Proxy for already instantiated classes
public $allowed_overrides = array('threshold' => 1, 'lifetime' => 1, 'decay_speed' => 1);
@ -263,6 +266,10 @@ class DecayingModel extends AppModel
// - full attach Attribute types associated to the requested model
public function fetchModel($user, $id, $full=true, $conditions=array(), $attach_editable=0)
{
$cacheKey = sprintf('%s', $id);
if (isset($this->modelCache[$cacheKey])) {
return $this->modelCache[$cacheKey];
}
$conditions['id'] = $id;
$searchOptions = array(
'conditions' => $conditions,
@ -290,6 +297,7 @@ class DecayingModel extends AppModel
$decayingModel['DecayingModel']['attribute_types'] = $this->DecayingModelMapping->getAssociatedTypes($user, $decayingModel);
}
$decayingModel = $this->attachIsEditableByCurrentUser($user, $decayingModel);
$this->modelCache[$cacheKey] = $decayingModel;
return $decayingModel;
}
@ -612,11 +620,15 @@ class DecayingModel extends AppModel
if ($model_id === false) { // fetch all allowed and associated models
$associated_model_ids = $this->DecayingModelMapping->getAssociatedModels($user, $attribute['type'], true);
$associated_model_ids = isset($associated_model_ids[$attribute['type']]) ? array_values($associated_model_ids[$attribute['type']]) : array();
if (!empty($associated_model_ids)) {
if (isset($this->modelCacheForType[$attribute['type']])) {
$models = $this->modelCacheForType[$attribute['type']];
} else if (!empty($associated_model_ids)) {
$models = $this->fetchModels($user, $associated_model_ids, false, array('enabled' => true));
$this->modelCacheForType[$attribute['type']] = $models;
}
} else {
$models = $this->fetchModels($user, $model_id, false, array());
$this->modelCacheForType[$attribute['type']] = $models;
}
foreach ($models as $model) {
if (!empty($model_overrides)) {

View File

@ -25,6 +25,8 @@ class DecayingModelMapping extends AppModel
)
);
private $modelCache = [];
public function resetMappingForModel($new_model, $user) {
if (empty($new_model['model_id'])) {
throw new NotFoundException(__('No Decaying Model with the provided ID exists'));
@ -76,6 +78,10 @@ class DecayingModelMapping extends AppModel
}
public function getAssociatedModels($user, $attribute_type = false) {
$cacheKey = sprintf('%s', $attribute_type);
if (isset($this->modelCache[$cacheKey])) {
return $this->modelCache[$cacheKey];
}
$conditions = array(
'OR' => array(
'DecayingModel.org_id' => $user['org_id'],
@ -111,6 +117,7 @@ class DecayingModelMapping extends AppModel
}
$associated_models = Hash::combine($associated_models, '{n}.DecayingModelMapping.model_id', '{n}.DecayingModelMapping.model_id', '{n}.DecayingModelMapping.attribute_type');
$models = array_merge_recursive($associated_default_models, $associated_models);
$this->modelCache[$cacheKey] = $models;
return $models;
}

View File

@ -133,9 +133,9 @@ abstract class DecayingModelBase
}
if ($last_sighting_timestamp === false) {
$this->Sighting = ClassRegistry::init('Sighting');
$all_sightings = $this->Sighting->listSightings($user, $attribute['id'], 'attribute', false, 0, true);
if (!empty($all_sightings)) {
$last_sighting_timestamp = $all_sightings[0]['Sighting']['date_sighting'];
$last_sighting = $this->Sighting->getLastSightingForAttribute($attribute['id']);
if (!empty($last_sighting)) {
$last_sighting_timestamp = $last_sighting['Sighting']['date_sighting'];
} elseif (!is_null($attribute['last_seen'])) {
$last_sighting_timestamp = (new DateTime($attribute['last_seen']))->format('U');
} else {

View File

@ -1010,6 +1010,23 @@ class Sighting extends AppModel
return $sightings;
}
/**
* @param int $id
* @return array
*/
public function getLastSightingForAttribute($id): array
{
$sighting = $this->find('first', [
'conditions' => [
'Sighting.attribute_id' => $id,
'Sighting.type' => 0,
],
'recursive' => -1,
'order' => ['Sighting.date_sighting DESC']
]);
return empty($sighting) ? [] : $sighting;
}
/**
* @param array $user
* @param string $returnFormat