]> git.mxchange.org Git - friendica.git/blob - include/cache.php
Merge pull request #2861 from annando/1610-performance
[friendica.git] / include / cache.php
1 <?php
2 /**
3  * @file include/cache.php
4  *
5  * @brief Class for storing data for a short time
6  */
7
8 use \Friendica\Core\Config;
9 use \Friendica\Core\PConfig;
10
11 class Cache {
12         /**
13          * @brief Check for memcache and open a connection if configured
14          *
15          * @return object|boolean The memcache object - or "false" if not successful
16          */
17         public static function memcache() {
18                 if (!function_exists('memcache_connect')) {
19                         return false;
20                 }
21
22                 if (!Config::get('system', 'memcache')) {
23                         return false;
24                 }
25
26                 $memcache_host = Config::get('system', 'memcache_host', '127.0.0.1');
27                 $memcache_port = Config::get('system', 'memcache_port', 11211);
28
29                 $memcache = new Memcache;
30
31                 if (!$memcache->connect($memcache_host, $memcache_port)) {
32                         return false;
33                 }
34
35                 return $memcache;
36         }
37
38         /**
39          * @brief Return the duration for a given cache level
40          *
41          * @param integer $level Cache level
42          *
43          * @return integer The cache duration in seconds
44          */
45         private function duration($level) {
46                 switch($level) {
47                         case CACHE_MONTH;
48                                 $seconds = 2592000;
49                                 break;
50                         case CACHE_WEEK;
51                                 $seconds = 604800;
52                                 break;
53                         case CACHE_DAY;
54                                 $seconds = 86400;
55                                 break;
56                         case CACHE_HOUR;
57                                 $seconds = 3600;
58                                 break;
59                         case CACHE_HALF_HOUR;
60                                 $seconds = 1800;
61                                 break;
62                         case CACHE_QUARTER_HOUR;
63                                 $seconds = 900;
64                                 break;
65                         case CACHE_FIVE_MINUTES;
66                                 $seconds = 300;
67                                 break;
68                         case CACHE_MINUTE;
69                                 $seconds = 60;
70                                 break;
71                 }
72                 return $seconds;
73         }
74
75         /**
76          * @brief Fetch cached data according to the key
77          *
78          * @param string $key The key to the cached data
79          *
80          * @return mixed Cached $value or "null" if not found
81          */
82         public static function get($key) {
83
84                 $memcache = self::memcache();
85                 if (is_object($memcache)) {
86                         // We fetch with the hostname as key to avoid problems with other applications
87                         $value = $memcache->get(get_app()->get_hostname().":".$key);
88                         if (!is_bool($value)) {
89                                 return unserialize($value);
90                         }
91
92                         return null;
93                 }
94
95                 // Frequently clear cache
96                 self::clear($duration);
97
98                 $r = q("SELECT `v` FROM `cache` WHERE `k`='%s' LIMIT 1",
99                         dbesc($key)
100                 );
101
102                 if (count($r)) {
103                         return $r[0]['v'];
104                 }
105
106                 return null;
107         }
108
109         /**
110          * @brief Put data in the cache according to the key
111          *
112          * @param string $key The key to the cached data
113          * @param mixed $valie The value that is about to be stored
114          * @param integer $duration The cache lifespan
115          */
116         public static function set($key, $value, $duration = CACHE_MONTH) {
117
118                 // Do we have an installed memcache? Use it instead.
119                 $memcache = self::memcache();
120                 if (is_object($memcache)) {
121                         // We store with the hostname as key to avoid problems with other applications
122                         $memcache->set(get_app()->get_hostname().":".$key, serialize($value), MEMCACHE_COMPRESSED, self::duration($duration));
123                         return;
124                 }
125
126                 /// @todo store the cache data in the same way like the config data
127                 q("REPLACE INTO `cache` (`k`,`v`,`expire_mode`,`updated`) VALUES ('%s','%s',%d,'%s')",
128                                 dbesc($key),
129                                 dbesc($value),
130                                 intval($duration),
131                                 dbesc(datetime_convert()));
132         }
133
134         /**
135          * @brief Remove outdated data from the cache
136          *
137          * @param integer $maxlevel The maximum cache level that is to be cleared
138          */
139         public static function clear($max_level = CACHE_MONTH) {
140
141                 // Clear long lasting cache entries only once a day
142                 if (get_config("system", "cache_cleared_day") < time() - self::duration(CACHE_DAY)) {
143                         if ($max_level == CACHE_MONTH) {
144                                 q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
145                                         dbesc(datetime_convert('UTC','UTC',"now - 30 days")), intval(CACHE_MONTH));
146                         }
147
148                         if ($max_level <= CACHE_WEEK) {
149                                 q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
150                                         dbesc(datetime_convert('UTC','UTC',"now - 7 days")), intval(CACHE_WEEK));
151                         }
152
153                         if ($max_level <= CACHE_DAY) {
154                                 q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
155                                 dbesc(datetime_convert('UTC','UTC',"now - 1 days")), intval(CACHE_DAY));
156                         }
157                         set_config("system", "cache_cleared_day", time());
158                 }
159
160                 if (($max_level <= CACHE_HOUR) AND (get_config("system", "cache_cleared_hour")) < time() - self::duration(CACHE_HOUR)) {
161                         q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
162                                 dbesc(datetime_convert('UTC','UTC',"now - 1 hours")), intval(CACHE_HOUR));
163
164                         set_config("system", "cache_cleared_hour", time());
165                 }
166
167                 if (($max_level <= CACHE_HALF_HOUR) AND (get_config("system", "cache_cleared_half_hour")) < time() - self::duration(CACHE_HALF_HOUR)) {
168                         q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
169                                 dbesc(datetime_convert('UTC','UTC',"now - 30 minutes")), intval(CACHE_HALF_HOUR));
170
171                         set_config("system", "cache_cleared_half_hour", time());
172                 }
173
174                 if (($max_level <= CACHE_QUARTER_HOUR) AND (get_config("system", "cache_cleared_hour")) < time() - self::duration(CACHE_QUARTER_HOUR)) {
175                         q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
176                                 dbesc(datetime_convert('UTC','UTC',"now - 15 minutes")), intval(CACHE_QUARTER_HOUR));
177
178                         set_config("system", "cache_cleared_quarter_hour", time());
179                 }
180
181                 if (($max_level <= CACHE_FIVE_MINUTES) AND (get_config("system", "cache_cleared_five_minute")) < time() - self::duration(CACHE_FIVE_MINUTES)) {
182                         q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
183                                 dbesc(datetime_convert('UTC','UTC',"now - 5 minutes")), intval(CACHE_FIVE_MINUTES));
184
185                         set_config("system", "cache_cleared_five_minute", time());
186                 }
187
188                 if (($max_level <= CACHE_MINUTE) AND (get_config("system", "cache_cleared_minute")) < time() - self::duration(CACHE_MINUTE)) {
189                         q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
190                                 dbesc(datetime_convert('UTC','UTC',"now - 1 minutes")), intval(CACHE_MINUTE));
191
192                         set_config("system", "cache_cleared_minute", time());
193                 }
194         }
195 }