aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+studip@gmail.com>2023-09-28 10:55:33 +0000
committerJan-Hendrik Willms <tleilax+studip@gmail.com>2023-09-28 10:55:33 +0000
commit2bbcfb7bbda30fc0588c1093c9eef36f27d22a60 (patch)
tree7967ff64bc37752f1e0a45fd4852119efe23d648
parent9e3cfdbe768375994ca61d22c11039c151e95239 (diff)
proposal for caching, re #3234
Merge request studip/studip!2194
-rw-r--r--lib/classes/StudipTreeNodeCachableTrait.php59
-rw-r--r--lib/models/RangeTreeNode.php18
-rw-r--r--lib/models/StudipStudyArea.class.php18
3 files changed, 70 insertions, 25 deletions
diff --git a/lib/classes/StudipTreeNodeCachableTrait.php b/lib/classes/StudipTreeNodeCachableTrait.php
new file mode 100644
index 0000000..31823ac
--- /dev/null
+++ b/lib/classes/StudipTreeNodeCachableTrait.php
@@ -0,0 +1,59 @@
+<?php
+trait StudipTreeNodeCachableTrait
+{
+ protected static $descendants_cache_array = null;
+
+ protected static function getDescendantsCacheArray(): StudipCachedArray
+ {
+ if (self::$descendants_cache_array === null) {
+ self::$descendants_cache_array = new StudipCachedArray(
+ static::class . '/descendants',
+ 30 * 60
+ );
+ }
+ return self::$descendants_cache_array;
+ }
+
+ protected static function registerCachableCallbacks(array $config): array
+ {
+ if (!isset($config['registered_callbacks'])) {
+ $config['registered_callbacks'] = [];
+ }
+
+ if (!isset($config['registered_callbacks']['before_store'])) {
+ $config['registered_callbacks']['before_store'] = [];
+ }
+ $config['registered_callbacks']['before_store'][] = function ($node): void {
+ self::getDescendantsCacheArray()->expire();
+ };
+
+ if (!isset($config['registered_callbacks']['after_delete'])) {
+ $config['registered_callbacks']['after_delete'] = [];
+ }
+ $config['registered_callbacks']['after_delete'][] = function ($node): void {
+ self::getDescendantsCacheArray()->expire();
+ };
+
+ return $config;
+ }
+
+ protected function getDescendantIds(): array
+ {
+ $cache = self::getDescendantsCacheArray();
+
+ if (isset($cache[$this->id])) {
+ return $cache[$this->id];
+ }
+
+ $ids = [];
+
+ foreach ($this->getChildNodes() as $child) {
+ $ids = array_merge($ids, [$child->id], $child->getDescendantIds());
+ }
+
+ $cache[$this->id] = $ids;
+
+ return $ids;
+ }
+
+}
diff --git a/lib/models/RangeTreeNode.php b/lib/models/RangeTreeNode.php
index 4d52fed..c142579 100644
--- a/lib/models/RangeTreeNode.php
+++ b/lib/models/RangeTreeNode.php
@@ -27,6 +27,8 @@
*/
class RangeTreeNode extends SimpleORMap implements StudipTreeNode
{
+ use StudipTreeNodeCachableTrait;
+
protected static function configure($config = [])
{
$config['db_table'] = 'range_tree';
@@ -41,12 +43,13 @@ class RangeTreeNode extends SimpleORMap implements StudipTreeNode
];
$config['has_many']['children'] = [
'class_name' => RangeTreeNode::class,
- 'foreign_key' => 'item_id',
'assoc_foreign_key' => 'parent_id',
'order_by' => 'ORDER BY priority, name',
- 'on_delete' => 'delete'
+ 'on_delete' => 'delete',
];
+ $config = self::registerCachableCallbacks($config);
+
parent::configure($config);
}
@@ -240,17 +243,6 @@ class RangeTreeNode extends SimpleORMap implements StudipTreeNode
return DBManager::get()->fetchAll($query, $parameters, 'Course::buildExisting');
}
- public function getDescendantIds()
- {
- $ids = [];
-
- foreach ($this->children as $child) {
- $ids = array_merge($ids, [$child->id], $child->getDescendantIds());
- }
-
- return $ids;
- }
-
public function getAncestors(): array
{
$path = [
diff --git a/lib/models/StudipStudyArea.class.php b/lib/models/StudipStudyArea.class.php
index 1ea7722..518e6c1 100644
--- a/lib/models/StudipStudyArea.class.php
+++ b/lib/models/StudipStudyArea.class.php
@@ -30,6 +30,8 @@
class StudipStudyArea extends SimpleORMap implements StudipTreeNode
{
+ use StudipTreeNodeCachableTrait;
+
/**
* This constant represents the key of the root area.
*/
@@ -53,6 +55,9 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode
'class_name' => StudipStudyArea::class,
'foreign_key' => 'parent_id',
];
+
+ $config = self::registerCachableCallbacks($config);
+
parent::configure($config);
}
@@ -64,7 +69,7 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode
/**
* Returns the children of the study area with the specified ID.
*/
- static function findByParent($parent_id)
+ public static function findByParent($parent_id)
{
return self::findByparent_id($parent_id, "ORDER BY priority,name");
}
@@ -601,17 +606,6 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode
return $path;
}
- private function getDescendantIds()
- {
- $ids = [];
-
- foreach ($this->_children as $child) {
- $ids = array_merge($ids, [$child->id], $child->getDescendantIds());
- }
-
- return $ids;
- }
-
/**
* Constructs an index from the level hierarchy, This index is a number,
* containing the "depth" level and the priority on this level. For example,