Skip to content

Commit

Permalink
Use selective bug cache for attachment count
Browse files Browse the repository at this point in the history
Fetch data only for bugs included in filter result set
instead of reading the full table and storing it in cache

fixes #0020138
  • Loading branch information
cproensa authored and dregad committed Nov 11, 2016
1 parent fcad575 commit 624982b
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 27 deletions.
72 changes: 46 additions & 26 deletions core/file_api.php
Expand Up @@ -98,45 +98,65 @@ function file_get_display_name( $p_filename ) {
}

/**
* Check the number of attachments a bug has (if any)
* @param integer $p_bug_id A bug identifier.
* @return integer
* Fills the cache with the attachement count from a list of bugs
* If the bug doesn't have attachments, cache its value as 0.
* @global array $g_cache_file_count
* @param array $p_bug_ids Array of bug ids
* @return void
*/
function file_bug_attachment_count( $p_bug_id ) {
function file_bug_attachment_count_cache( array $p_bug_ids ) {
global $g_cache_file_count;

# First check if we have a cache hit
if( isset( $g_cache_file_count[$p_bug_id] ) ) {
return $g_cache_file_count[$p_bug_id];
if( empty( $p_bug_ids ) ) {
return;
}

# If there is no cache hit, check if there is anything in
# the cache. If the cache isn't empty and we didn't have
# a hit, then there are not attachments for this bug.
if( count( $g_cache_file_count ) > 0 ) {
return 0;
$t_ids_to_search = array();
foreach( $p_bug_ids as $t_id ) {
$c_id = (int)$t_id;
$t_ids_to_search[$c_id] = $c_id;
}

# Otherwise build the cache and return the attachment count
# for the given bug (if any).
$t_query = 'SELECT bug_id, COUNT(bug_id) AS attachments FROM {bug_file} GROUP BY bug_id';
$t_result = db_query( $t_query );
db_param_push();
$t_params = array();
$t_in_values = array();
foreach( $t_ids_to_search as $t_id ) {
$t_params[] = (int)$t_id;
$t_in_values[] = db_param();
}

$t_query = 'SELECT B.id AS bug_id, COUNT(F.bug_id) AS attachments'
. ' FROM {bug} B JOIN {bug_file} F ON ( B.id = F.bug_id )'
. ' WHERE B.id IN (' . implode( ',', $t_in_values ) . ')'
. ' GROUP BY B.id';

$t_file_count = 0;
$t_result = db_query( $t_query, $t_params );
while( $t_row = db_fetch_array( $t_result ) ) {
$g_cache_file_count[$t_row['bug_id']] = $t_row['attachments'];
if( $p_bug_id == $t_row['bug_id'] ) {
$t_file_count = $t_row['attachments'];
}
$c_bug_id = (int)$t_row['bug_id'];
$g_cache_file_count[$c_bug_id] = (int)$t_row['attachments'];
unset( $t_ids_to_search[$c_bug_id] );
}

# If no attachments are present, mark the cache to avoid
# repeated queries for this.
if( count( $g_cache_file_count ) == 0 ) {
$g_cache_file_count['_no_files_'] = -1;
# set bugs without result to 0
foreach( $t_ids_to_search as $t_id ) {
$g_cache_file_count[$t_id] = 0;
}
}

/**
* Check the number of attachments a bug has (if any)
* @param integer $p_bug_id A bug identifier.
* @return integer
*/
function file_bug_attachment_count( $p_bug_id ) {
global $g_cache_file_count;

# If it's not in cache, load the value
if( !isset( $g_cache_file_count[$p_bug_id] ) ) {
file_bug_attachment_count_cache( array( (int)$p_bug_id ) );
}

return $t_file_count;
return $g_cache_file_count[$p_bug_id];
}

/**
Expand Down
6 changes: 5 additions & 1 deletion core/filter_api.php
Expand Up @@ -2225,21 +2225,25 @@ function filter_get_bug_rows_query_clauses( array $p_filter, $p_project_id = nul

/**
* Cache the filter results with bugnote stats for later use
* also fills bug attachment count cache
* @param array $p_rows Results of the filter query.
* @param array $p_id_array_lastmod Array of bug ids.
* @return array
*/
function filter_cache_result( array $p_rows, array $p_id_array_lastmod ) {
$t_stats = bug_get_bugnote_stats_array( $p_id_array_lastmod );
$t_rows = array();
$t_bug_ids = array();
foreach( $p_rows as $t_row ) {
$b = $t_stats[$t_row['id']];
$t_bug_ids[] = (int)$t_row['id'];
if( array_key_exists( $t_row['id'], $t_stats ) ) {
$t_rows[] = bug_row_to_object( bug_cache_database_result( $t_row, $t_stats[$t_row['id']] ) );
} else {
$t_rows[] = bug_row_to_object( bug_cache_database_result( $t_row ) );
}
}
#cache the attachment count for bug list
file_bug_attachment_count_cache( $t_bug_ids );
return $t_rows;
}

Expand Down

0 comments on commit 624982b

Please sign in to comment.