issue #2202 factorize (and use cache) to build filters

This commit is contained in:
plegall
2024-08-07 22:07:35 +02:00
parent bfe1e85801
commit dd6d1a91d7
2 changed files with 85 additions and 159 deletions
+68
View File
@@ -616,6 +616,74 @@ SELECT
);
}
/**
* Returns the SQL WHERE clause to be used to build filter values
*
* @since 15
*
* @param string $filter_name
*
* @return string
*/
function get_clause_for_filter($filter_name)
{
global $page;
$other_filters_items = get_items_for_filter($filter_name);
if (false === $other_filters_items)
{
return '1=1'.$page['search_details']['forbidden'];
}
return 'image_id IN ('.implode(',', $other_filters_items).')';
}
/**
* Returns the list of items (image_ids) to be used to build filter values
* for a given filter. Depends on the other filters. Use a cache to avoid
* computing the same large array_intersect several times.
*
* @since 15
*
* @param string $filter_name
*
* @return array of image_ids (or false)
*/
function get_items_for_filter($filter_name)
{
global $page, $logger;
$other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array($filter_name));
if (empty($other_filters))
{
return false;
}
$cache_key = md5(implode(',', $other_filters));
if (!isset($page['search_details'][__FUNCTION__][$cache_key]))
{
$function_start = get_moment();
$other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)];
foreach ($other_filters as $other_filter)
{
$other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]);
}
$other_filters_items = array_unique($other_filters_items);
$debug_msg = '['.__FUNCTION__.'] cache computed for '.(count($other_filters)+1).' other filters';
$debug_msg.= ' ('.count($other_filters_items).' items)';
$debug_msg.= ', time = '.get_elapsed_time($function_start, get_moment());
$logger->debug($debug_msg);
@$page['search_details'][__FUNCTION__][$cache_key] = $other_filters_items;
}
return $page['search_details'][__FUNCTION__][$cache_key];
}
define('QST_QUOTED', 0x01);
+17 -159
View File
@@ -183,7 +183,7 @@ if ( empty($page['is_external']) )
$my_search = get_search_array($page['search']);
$search_forbidden = get_sql_condition_FandF(
$page['search_details']['forbidden'] = get_sql_condition_FandF(
array(
'forbidden_categories' => 'category_id',
'visible_categories' => 'category_id',
@@ -215,16 +215,14 @@ if ( empty($page['is_external']) )
// TODO calling get_available_tags(), with lots of photos/albums/tags may cost time,
// we should reuse the result if already executed (for building the menu for example)
$other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('tags'));
if (count($other_filters) > 0)
$other_filters_items = get_items_for_filter('tags');
if (false === $other_filters_items)
{
$filter_tags = get_available_tags();
usort($filter_tags, 'tag_alpha_compare');
}
else
{
$other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)];
foreach ($other_filters as $other_filter)
{
$other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]);
}
$other_filters_items = array_unique($other_filters_items);
$filter_tags = get_common_tags($other_filters_items, 0);
// the user may have started a search on 2 or more tags that have no
@@ -238,11 +236,6 @@ if ( empty($page['is_external']) )
$filter_tags = array_merge(get_available_tags($missing_tag_ids), $filter_tags);
}
}
else
{
$filter_tags = get_available_tags();
usort($filter_tags, 'tag_alpha_compare');
}
$template->assign('TAGS', $filter_tags);
@@ -254,22 +247,7 @@ if ( empty($page['is_external']) )
if (isset($my_search['fields']['author']))
{
$other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('author'));
if (count($other_filters) > 0)
{
$other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)];
foreach ($other_filters as $other_filter)
{
$other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]);
}
$other_filters_items = array_unique($other_filters_items);
$filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')';
}
else
{
$filter_clause = '1=1'.$search_forbidden;
}
$filter_clause = get_clause_for_filter('author');
$query = '
SELECT
@@ -295,22 +273,7 @@ SELECT
if (isset($my_search['fields']['date_posted']))
{
$other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('date_posted'));
if (count($other_filters) > 0)
{
$other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)];
foreach ($other_filters as $other_filter)
{
$other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]);
}
$other_filters_items = array_unique($other_filters_items);
$filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')';
}
else
{
$filter_clause = '1=1'.$search_forbidden;
}
$filter_clause = get_clause_for_filter('date_posted');
$query = '
SELECT
@@ -390,22 +353,7 @@ SELECT
if (isset($my_search['fields']['added_by']))
{
$other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('added_by'));
if (count($other_filters) > 0)
{
$other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)];
foreach ($other_filters as $other_filter)
{
$other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]);
}
$other_filters_items = array_unique($other_filters_items);
$filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')';
}
else
{
$filter_clause = '1=1'.$search_forbidden;
}
$filter_clause = get_clause_for_filter('added_by');
$query = '
SELECT
@@ -483,22 +431,7 @@ SELECT
if (isset($my_search['fields']['filetypes']))
{
$other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('filetypes'));
if (count($other_filters) > 0)
{
$other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)];
foreach ($other_filters as $other_filter)
{
$other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]);
}
$other_filters_items = array_unique($other_filters_items);
$filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')';
}
else
{
$filter_clause = '1=1'.$search_forbidden;
}
$filter_clause = get_clause_for_filter('filetypes');
$query = '
SELECT
@@ -516,22 +449,7 @@ SELECT
// For rating
if (isset($my_search['fields']['ratings']))
{
$other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('ratings'));
if (count($other_filters) > 0)
{
$other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)];
foreach ($other_filters as $other_filter)
{
$other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]);
}
$other_filters_items = array_unique($other_filters_items);
$filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')';
}
else
{
$filter_clause = '1=1'.$search_forbidden;
}
$filter_clause = get_clause_for_filter('ratings');
$ratings = array_fill(0, 6, 0);
@@ -573,22 +491,7 @@ SELECT
// For filesize
if (isset($my_search['fields']['filesize_min']) && isset($my_search['fields']['filesize_max']))
{
$other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('filesize'));
if (count($other_filters) > 0)
{
$other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)];
foreach ($other_filters as $other_filter)
{
$other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]);
}
$other_filters_items = array_unique($other_filters_items);
$filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')';
}
else
{
$filter_clause = '1=1'.$search_forbidden;
}
$filter_clause = get_clause_for_filter('filesize');
$filesizes = array();
$filesize = array();
@@ -635,22 +538,7 @@ SELECT
if (isset($my_search['fields']['ratios']))
{
$other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('ratios'));
if (count($other_filters) > 0)
{
$other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)];
foreach ($other_filters as $other_filter)
{
$other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]);
}
$other_filters_items = array_unique($other_filters_items);
$filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')';
}
else
{
$filter_clause = '1=1'.$search_forbidden;
}
$filter_clause = get_clause_for_filter('ratios');
$query = '
SELECT
@@ -696,22 +584,7 @@ SELECT
if (isset($my_search['fields']['height_min']) and isset($my_search['fields']['height_max']))
{
$other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('height'));
if (count($other_filters) > 0)
{
$other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)];
foreach ($other_filters as $other_filter)
{
$other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]);
}
$other_filters_items = array_unique($other_filters_items);
$filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')';
}
else
{
$filter_clause = '1=1'.$search_forbidden;
}
$filter_clause = get_clause_for_filter('height');
$query = '
SELECT
@@ -742,22 +615,7 @@ SELECT
if (isset($my_search['fields']['width_min']) and isset($my_search['fields']['width_max']))
{
$other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('width'));
if (count($other_filters) > 0)
{
$other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)];
foreach ($other_filters as $other_filter)
{
$other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]);
}
$other_filters_items = array_unique($other_filters_items);
$filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')';
}
else
{
$filter_clause = '1=1'.$search_forbidden;
}
$filter_clause = get_clause_for_filter('width');
$query = '
SELECT