1, ]; public function __construct(array $attributes = []) { parent::__construct($attributes); if (! $this->exists) { // only allow mempool_perc_warn to be filled for new mempools unset($this->fillable[array_search('mempool_perc_warn', $this->fillable)]); } } public function isValid() { return $this->mempool_total > 0; } public function fillUsage($used = null, $total = null, $free = null, $percent = null) { try { $total = $this->correctNegative($total); $used = $this->correctNegative($used, $total); $free = $this->correctNegative($free, $total); } catch (\Exception $e) { d_echo($e->getMessage()); return $this; // unhandled negative } $this->mempool_total = $this->calculateTotal($total, $used, $free); $this->mempool_used = $used * $this->mempool_precision; $this->mempool_free = $free * $this->mempool_precision; $percent = $this->normalizePercent($percent); // don't assign to model or it loses precision $this->mempool_perc = $percent; if (! $this->mempool_total) { if (! $percent && $percent !== 0.0) { // could not calculate total, can't calculate other values return $this; } $this->mempool_total = 100; // only have percent, mark total as 100 } if ($used === null) { $this->mempool_used = $free !== null ? $this->mempool_total - $this->mempool_free : round($this->mempool_total * ($percent ? ($percent / 100) : 0)); } if ($free === null) { $this->mempool_free = $used !== null ? $this->mempool_total - $this->mempool_used : round($this->mempool_total * ($percent ? (1 - ($percent / 100)) : 1)); } if ($percent == null) { $this->mempool_perc = (int) Number::calculatePercent($this->mempool_used, $this->mempool_total, 0); } return $this; } /** * Set the mempool class. If no class is given, try to detect it from available data. * * @param string $class * @param string $default * @return \App\Models\Mempool */ public function setClass($class = null, $default = 'system') { if ($class) { $this->mempool_class = $class; return $this; } $memoryClasses = [ 'virtual' => ['virtual'], 'swap' => ['swap'], 'buffers' => ['buffers'], 'cached' => ['cache'], 'system' => ['shared real memory metrics'], 'shared' => ['shared'], ]; $descr = strtolower($this->mempool_descr); foreach ($memoryClasses as $class => $search) { if (Str::contains($descr, $search)) { $this->mempool_class = $class; return $this; } } if ($default == 'virtual' && Str::contains($this->mempool_descr, ['/dev/'])) { $this->mempool_class = 'swap'; return $this; } $this->mempool_class = $default; return $this; } public function setMempoolPercAttribute($percent) { $this->attributes['mempool_perc'] = is_numeric($percent) ? round($percent) : null; } public function getCompositeKey() { return "$this->mempool_type-$this->mempool_index"; } private function correctNegative($value, $max = null) { $int_max = 4294967296; if ($value < 0) { // assume unsigned/signed issue $value = $int_max + $value; if (($max && $value > $max) || $value > $int_max) { throw new \Exception('Uncorrectable negative value'); } } return $value; } private function calculateTotal($total, $used, $free) { if ($total !== null) { return (int) $total * $this->mempool_precision; } if ($used !== null && $free !== null) { return ($used + $free) * $this->mempool_precision; } return $this->mempool_total; // don't change the value it may have been set in discovery } private function normalizePercent($percent) { if ($percent === null) { return null; } $percent = floatval($percent); while ($percent > 100) { $percent = $percent / 10; } return $percent; } }