Add methods to cache content (for example, on heavy postgres queries)

This commit is contained in:
Bofh 2022-12-02 16:53:24 +01:00
parent d54d60bc9f
commit ed2e7c453a
3 changed files with 72 additions and 6 deletions

View File

@ -66,7 +66,14 @@ if (isset($_GET['no_statuses']))
$sql_all = str_replace('{noStatusesWhere}', '(SELECT count(1) FROM statuses WHERE account_id = a.id) = 0 AND', $sql_all);
else $sql_all = str_replace('{noStatusesWhere}', '', $sql_all);
$all_accounts = $pg->fetch_all($sql_all);
$cache = null;
if ($user_filter === 'local')
$cache = 'ondemand,60';
else if (in_array($user_filter, ['all','remote']))
$cache = 'ondemand,300';
$all_accounts = $pg->fetch_all($sql_all, $cache);
if (isset($_GET['profile']) && trim($_GET['profile']) != '')
{
@ -151,9 +158,9 @@ foreach ($filtered_accounts as $id) {
$newacc['avatar'] .= '/accounts/avatars/'.implode('/',$parts).'/original/'.$account['avatar_file_name'];
}
$following = $pg->fetch_one('SELECT count(1) FROM follows WHERE account_id = \''.$id.'\'');
$following = $pg->fetch('SELECT count(1) FROM follows WHERE account_id = \''.$id.'\'');
$newacc['following'] = intval($following['count']);
$followers = $pg->fetch_one('SELECT count(1) FROM follows WHERE target_account_id = \''.$id.'\'');
$followers = $pg->fetch('SELECT count(1) FROM follows WHERE target_account_id = \''.$id.'\'');
$newacc['followers'] = intval($followers['count']);
if (isset($_GET['no_follows']) && $newacc['following'] > 0 && $newacc['followers'] > 0)
continue;

View File

@ -273,5 +273,49 @@ function normalize_for_search($str) {
return trim(implode(' ', $newwords));
}
function content_cache__exists($key) {
$cache_dir = $GLOBALS['appconf']['data_dir'].'/cache';
if (!file_exists($cache_dir)) {
mkdir($cache_dir);
return false;
}
$key = md5($key);
$cache_file = null;
foreach (scandir($cache_dir) as $fil) {
if (strpos($fil, $key) !== false) {
$cache_file = $cache_dir.'/'.$fil;
$ps = explode(',',$fil);
array_splice($ps, 0, 1);
$ps[1] = intval($ps[1]);
return (object)[
'file' => $cache_file,
'config' => $ps
];
}
}
return false;
}
function content_cache__get($key) {
$cfg = content_cache__exists($key);
if ($cfg === false)
return null;
$ms = time() - filemtime($cfg->file);
if ($cfg->config[0] === 'ondemand' &&
$ms > $cfg->config[1]) {
unlink($cfg->file);
return null;
}
return unserialize(file_get_contents($cfg->file));
}
function content_cache__put($key, $config, $data) {
$cache_dir = $GLOBALS['appconf']['data_dir'].'/cache';
if (!file_exists($cache_dir))
mkdir($cache_dir);
$cache_file = $cache_dir.'/'.md5($key);
file_put_contents($cache_file.','.$config, serialize($data));
}
// classes
require 'classes/PgDatabase.php';

View File

@ -36,18 +36,33 @@ class PgDatabase {
return $result;
}
public function fetch_one($sql) {
public function fetch($sql, $cache=null) {
if ($cache !== null) {
$cached = content_cache__get($sql);
if ($cached !== null)
return $cached;
}
$result = $this->query($sql);
return pg_fetch_assoc($result);
$data = pg_fetch_assoc($result);
if ($cache !== null)
content_cache__put($sql, $cache, $data);
return $data;
}
public function fetch_all($sql) {
public function fetch_all($sql, $cache=null) {
if ($cache !== null) {
$cached = content_cache__get($sql);
if ($cached !== null)
return $cached;
}
$data = [];
$result = $this->query($sql);
while ($line = pg_fetch_array($result, null, PGSQL_ASSOC)) {
$data []= $line;
}
pg_free_result($result);
if ($cache !== null)
content_cache__put($sql, $cache, $data);
return $data;
}