Same name and namespace in other branches
  1. 7.x-2.x advagg_bundler/advagg_bundler.advagg.inc \advagg_bundler_merge() 1 comment

Merge bundles together if too many where created.

This preserves the order.

Parameters

$groupings: array of requested groups

$max: max number of grouping

1 call to advagg_bundler_merge()
advagg_bundler_advagg_filenames_alter in advagg_bundler/advagg_bundler.module
Implements hook_advagg_filenames_alter().

File

advagg_bundler/advagg_bundler.module, line 255

Code

function advagg_bundler_merge(&$groupings, $max) {
    $group_count = count($groupings);
    if (!empty($max)) {
        // Keep going till array has been merged to the desired size.
        while ($group_count > $max) {
            // Get array sizes.
            // Counts the number of files that are placed into each bundle.
            $counts = array();
            foreach ($groupings as $key => $values) {
                $counts[$key] = count($values);
            }
            // Create mapping.
            // Calculates the file count of potential merges. It only merges with
            // neighbors in order to preserve execution order.
            $map = array();
            $prev_key = '';
            foreach ($counts as $key => $val) {
                // First run of the foreach loop; populate prev key/values and continue.
                // We can't merge with the previous group in this case.
                if (empty($prev_key)) {
                    $prev_key = $key;
                    $prev_val = $val;
                    continue;
                }
                // Array key ($prev_val + $val) is the file count of this new group if
                // these 2 groups ($prev_key, $key) where to be merged together.
                $map[] = array(
                    $prev_val + $val => array(
                        $prev_key,
                        $key,
                    ),
                );
                $prev_key = $key;
                $prev_val = $val;
            }
            // Get best merge candidate.
            // We are looking for the smallest file count. $min is populated with a
            // large number (15 bits) so it won't be selected in this process.
            $min = 32767;
            foreach ($map as $v) {
                foreach ($v as $key => $values) {
                    $min = min($min, $key);
                    // If the min value (number of files in the proposed merged bundle) is
                    // the same as the key, then get the 2 bundle keys that generated this
                    // new min value.
                    if ($min == $key) {
                        list($first, $last) = $values;
                    }
                }
            }
            //       watchdog('debug', $first . "<br>\n" . $last . "<br>\n" . str_replace('    ', '&nbsp;&nbsp;&nbsp;&nbsp;', nl2br(htmlentities(print_r(array($groupings, $map, $counts), TRUE)))));
            // Create the new merged set
            $a = $groupings[$first];
            $b = $groupings[$last];
            $new_set = array_merge($a, $b);
            // Rebuild the array with the new set in the correct place.
            $new_groupings = array();
            foreach ($groupings as $key => $files) {
                if ($key == $first) {
                    $new_groupings[$first . ' ' . $last] = $new_set;
                }
                elseif ($key != $last) {
                    $new_groupings[$key] = $files;
                }
            }
            $groupings = $new_groupings;
            $group_count--;
        }
    }
    // Make sure there isn't a group that has all files that don't exist or empty.
    $bad_groups = array();
    $counts = array();
    foreach ($groupings as $key => $group) {
        $missing_counter = 0;
        $counts[$key] = count($group);
        foreach ($group as $i => $file) {
            advagg_clearstatcache(TRUE, $file);
            if (!file_exists($file) || filesize($file) == 0) {
                $missing_counter++;
            }
        }
        // If all files are missing/empty in this group then it is a bad set.
        if ($missing_counter == count($group)) {
            $bad_groups[$key] = TRUE;
        }
    }
    // Add the bad groups to the smallest grouping in this set.
    if (!empty($bad_groups)) {
        $merge_candidate_key = '';
        $merge_candidate_count = 32767;
        $bad_group = array();
        foreach ($groupings as $key => $group) {
            if (isset($bad_groups[$key])) {
                // Merge all bad groups into one.
                $bad_group = array_merge($bad_group, $group);
                // Delete the bad group from the master set.
                unset($groupings[$key]);
                continue;
            }
            // Find the smallest good grouping.
            $min = min($merge_candidate_count, count($group));
            if ($min < $merge_candidate_count) {
                $merge_candidate_key = $key;
                $merge_candidate_count = $min;
            }
        }
        // Move the bad files into the smallest good group.
        $new_set = $groupings[$merge_candidate_key];
        $new_set = array_merge($new_set, $bad_group);
        $groupings[$merge_candidate_key] = $new_set;
    }
    // Output Debugging info to watchdog.
    // watchdog('debug', str_replace('    ', '&nbsp;&nbsp;&nbsp;&nbsp;', nl2br(htmlentities(print_r($groupings, TRUE)))));
}