/**
 * Gets a sorted array of signature indexes from the supplied nodes.
 *
 * @param array $node_indexs
 *   The array of node indexes to get signatures from.
 * @param array $headers
 *   Header information from the data file.
 *
 * @return array
 *   A sorted array of signature indexes.
 */
function fiftyone_degrees_get_closest_signature_indexs($node_indexs, &$timings, &$debug_info, $headers)
{
    $node_count = count($node_indexs);
    if ($node_count == 1) {
        // There is only 1 list so return that single list.
        $node = fiftyone_degrees_read_node($node_indexs[0], $headers);
        fiftyone_degrees_fill_node_ranked_signatures($node, $headers['info']['max_signatures']);
        $sig_offsets = array();
        foreach ($node['node_ranked_signatures'] as $offset) {
            $sig_offsets[] = $offset;
        }
        return $sig_offsets;
    } else {
        $timings['closest_match_node_sort_time'] = microtime(TRUE);
        $sorted_nodes = array();
        $nodes = array();
        $max_count = 1;
        $iteration = 2;
        for ($i = 0; $i < $node_count; $i++) {
            $node = fiftyone_degrees_read_node($node_indexs[$i], $headers);
            $sorted_nodes[$i] = $node['node_ranked_signature_count'];
            $nodes[] = $node;
        }
        // Sort nodes in ascending order by signature count.
        array_multisort($sorted_nodes, SORT_ASC, $nodes);
        $timings['closest_match_node_sort_time'] = microtime(TRUE) - $timings['closest_match_node_sort_time'];
        $timings['closest_match_node_fill_signatures_time'] = microtime(TRUE);
        for ($i = 0; $i < $node_count; $i++) {
            fiftyone_degrees_fill_node_ranked_signatures($nodes[$i]);
        }
        $timings['closest_match_node_fill_signatures_time'] = microtime(TRUE) - $timings['closest_match_node_fill_signatures_time'];
        $timings['closest_match_filling_linked_list_time'] = microtime(TRUE);
        // Building initial list.
        $linked_list = new LinkedList();
        if (count($nodes) > 0) {
            $node_0_signatures_count = count($nodes[0]['node_ranked_signatures']);
            if ($node_0_signatures_count > $headers['info']['max_signatures']) {
                //  $node_0_signatures_count = $headers['info']['max_signatures'];
            }
            for ($i = 0; $i < $node_0_signatures_count; $i++) {
                $linked_list->addLast(array($nodes[0]['node_ranked_signatures'][$i], 1));
            }
        }
        // Count the number of times each signature index occurs.
        for ($i = 1; $i < $node_count; $i++) {
            $max_count = fiftyone_degrees_get_closest_signatures_for_node($node_count, $nodes[$i]['node_ranked_signatures'], $linked_list, $max_count, $iteration, $headers);
            $iteration++;
        }
        $timings['closest_match_filling_linked_list_time'] = microtime(TRUE) - $timings['closest_match_filling_linked_list_time'];
        $timings['closest_match_sorting_signature_ranks'] = microtime(TRUE);
        $sig_offsets = array();
        $linked_list->current = $linked_list->first;
        while ($linked_list->current !== -1) {
            if ($linked_list->current->value[1] == $max_count) {
                $debug_info['signatures_read']++;
                $sig_offsets[] = $linked_list->current->value[0];
            }
            $linked_list->moveNext();
        }
        $timings['closest_match_sorting_signature_ranks'] = microtime(TRUE) - $timings['closest_match_sorting_signature_ranks'];
        return $sig_offsets;
    }
}