mirror of https://github.com/MISP/MISP
chg: [correlation] Faster saving correlations
parent
c367e2b3a1
commit
1daab04ce2
|
@ -58,12 +58,18 @@ class DefaultCorrelationBehavior extends ModelBehavior
|
|||
return self::TABLE_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model $Model
|
||||
* @param string $value
|
||||
* @param array $a
|
||||
* @param array $b
|
||||
* @return array
|
||||
*/
|
||||
public function createCorrelationEntry(Model $Model, $value, $a, $b)
|
||||
{
|
||||
$valueId = $this->Correlation->CorrelationValue->getValueId($value);
|
||||
if ($this->deadlockAvoidance) {
|
||||
return [
|
||||
'value_id' => $valueId,
|
||||
'value_id' => $value,
|
||||
'1_event_id' => $a['Event']['id'],
|
||||
'1_object_id' => $a['Attribute']['object_id'],
|
||||
'1_attribute_id' => $a['Attribute']['id'],
|
||||
|
@ -87,7 +93,7 @@ class DefaultCorrelationBehavior extends ModelBehavior
|
|||
];
|
||||
} else {
|
||||
return [
|
||||
(int) $valueId,
|
||||
$value,
|
||||
(int) $a['Event']['id'],
|
||||
(int) $a['Attribute']['object_id'],
|
||||
(int) $a['Attribute']['id'],
|
||||
|
@ -112,7 +118,7 @@ class DefaultCorrelationBehavior extends ModelBehavior
|
|||
}
|
||||
}
|
||||
|
||||
public function saveCorrelations(Model $Model, $correlations)
|
||||
public function saveCorrelations(Model $Model, array $correlations)
|
||||
{
|
||||
$fields = [
|
||||
'value_id',
|
||||
|
@ -138,14 +144,23 @@ class DefaultCorrelationBehavior extends ModelBehavior
|
|||
'object_sharing_group_id'
|
||||
];
|
||||
|
||||
// Replace value with value ID
|
||||
$valueIndex = $this->deadlockAvoidance ? 'value_id' : 0;
|
||||
$values = array_column($correlations, $valueIndex);
|
||||
$valueIds = $this->Correlation->CorrelationValue->getIds($values);
|
||||
|
||||
foreach ($correlations as &$correlation) {
|
||||
$correlation[$valueIndex] = $valueIds[$correlation[$valueIndex]];
|
||||
}
|
||||
|
||||
if ($this->deadlockAvoidance) {
|
||||
return $this->Correlation->saveMany($correlations, array(
|
||||
return $this->Correlation->saveMany($correlations, [
|
||||
'atomic' => false,
|
||||
'callbacks' => false,
|
||||
'deep' => false,
|
||||
'validate' => false,
|
||||
'fieldList' => $fields
|
||||
));
|
||||
'fieldList' => $fields,
|
||||
]);
|
||||
} else {
|
||||
$db = $this->Correlation->getDataSource();
|
||||
// Split to chunks datasource is is enabled
|
||||
|
|
|
@ -6,7 +6,8 @@ App::uses('AppModel', 'Model');
|
|||
* @property Event $Event
|
||||
* @property CorrelationValue $CorrelationValue
|
||||
* @method saveCorrelations(array $correlations)
|
||||
* @method runBeforeSaveCorrelation
|
||||
* @method createCorrelationEntry(string $value, array $a, array $b)
|
||||
* @method runBeforeSaveCorrelation(array $attribute)
|
||||
* @method fetchRelatedEventIds(array $user, int $eventId, array $sgids)
|
||||
* @method getFieldRules
|
||||
* @method getContainRules($filter = null)
|
||||
|
@ -183,17 +184,6 @@ class Correlation extends AppModel
|
|||
return $correlatingAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param array $a Attribute A
|
||||
* @param array $b Attribute B
|
||||
* @return array
|
||||
*/
|
||||
private function __createCorrelationEntry($value, $a, $b)
|
||||
{
|
||||
return $this->createCorrelationEntry($value, $a, $b);
|
||||
}
|
||||
|
||||
public function correlateValue($value, $jobId = false)
|
||||
{
|
||||
$correlatingAttributes = $this->__getMatchingAttributes($value);
|
||||
|
@ -216,7 +206,7 @@ class Correlation extends AppModel
|
|||
if ($correlatingAttribute['Attribute']['event_id'] === $correlatingAttribute2['Attribute']['event_id']) {
|
||||
continue;
|
||||
}
|
||||
$correlations[] = $this->__createCorrelationEntry($value, $correlatingAttribute, $correlatingAttribute2);
|
||||
$correlations[] = $this->createCorrelationEntry($value, $correlatingAttribute, $correlatingAttribute2);
|
||||
}
|
||||
$extraCorrelations = $this->__addAdvancedCorrelations($correlatingAttribute);
|
||||
if (!empty($extraCorrelations)) {
|
||||
|
@ -224,8 +214,8 @@ class Correlation extends AppModel
|
|||
if ($correlatingAttribute['Attribute']['event_id'] === $extraCorrelation['Attribute']['event_id']) {
|
||||
continue;
|
||||
}
|
||||
$correlations[] = $this->__createCorrelationEntry($value, $correlatingAttribute, $extraCorrelation);
|
||||
//$correlations = $this->__createCorrelationEntry($value, $extraCorrelation, $correlatingAttribute, $correlations);
|
||||
$correlations[] = $this->createCorrelationEntry($value, $correlatingAttribute, $extraCorrelation);
|
||||
//$correlations = $this->createCorrelationEntry($value, $extraCorrelation, $correlatingAttribute, $correlations);
|
||||
}
|
||||
}
|
||||
if ($jobId && $k % 100 === 0) {
|
||||
|
@ -252,17 +242,16 @@ class Correlation extends AppModel
|
|||
}
|
||||
}
|
||||
|
||||
public function correlateAttribute(array $attribute)
|
||||
{
|
||||
$this->runBeforeSaveCorrelation($attribute);
|
||||
$this->afterSaveCorrelation($attribute);
|
||||
}
|
||||
|
||||
public function beforeSaveCorrelation(array $attribute)
|
||||
{
|
||||
$this->runBeforeSaveCorrelation($attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scope
|
||||
* @param int $id
|
||||
* @return false|array
|
||||
*/
|
||||
private function __cachedGetContainData($scope, $id)
|
||||
{
|
||||
if (!empty($this->getContainRules($scope))) {
|
||||
|
@ -390,9 +379,9 @@ class Correlation extends AppModel
|
|||
$value = $cV;
|
||||
}
|
||||
if ($a['Attribute']['id'] > $b['Attribute']['id']) {
|
||||
$correlations[] = $this->__createCorrelationEntry($value, $a, $b);
|
||||
$correlations[] = $this->createCorrelationEntry($value, $a, $b);
|
||||
} else {
|
||||
$correlations[] = $this->__createCorrelationEntry($value, $b, $a);
|
||||
$correlations[] = $this->createCorrelationEntry($value, $b, $a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,42 @@ class CorrelationValue extends AppModel
|
|||
{
|
||||
public $recursive = -1;
|
||||
|
||||
/**
|
||||
* @param array $values
|
||||
* @return array Value in key, value ID in value
|
||||
*/
|
||||
public function getIds(array $values)
|
||||
{
|
||||
foreach ($values as &$value) {
|
||||
$value = mb_substr($value, 0, 191);
|
||||
}
|
||||
$values = array_unique($values, SORT_REGULAR); // Remove duplicate values
|
||||
$existingValues = $this->find('list', [
|
||||
'recursive' => -1,
|
||||
'fields' => ['value', 'id'],
|
||||
'conditions' => [
|
||||
'value' => $values,
|
||||
]
|
||||
]);
|
||||
|
||||
$notExistValues = array_diff($values, array_keys($existingValues));
|
||||
if (!empty($notExistValues)) {
|
||||
$this->getDataSource()->begin();
|
||||
foreach ($notExistValues as $notExistValue) {
|
||||
$this->create();
|
||||
try {
|
||||
$this->save(['value' => $notExistValue]);
|
||||
$existingValues[$notExistValue] = $this->id;
|
||||
} catch (Exception $e) {
|
||||
$existingValues[$notExistValue] = $this->getValueId($notExistValue);
|
||||
}
|
||||
}
|
||||
$this->getDataSource()->commit();
|
||||
}
|
||||
|
||||
return $existingValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return int
|
||||
|
|
Loading…
Reference in New Issue