$id = 1; for ($tree = 1; $tree <= NR_OF_THREADS; $tree++) { $newnodes = array(array("id" => $id++, "parent_id" => 0, "subject" => "root")); for ($i = 1; $i < NR_OF_MESSAGES; $i++) { $j = array_rand($newnodes); $p = $newnodes[$j]; $subject = ''; $c = rand(1, 40); for ($k = 0; $k < $c; $k++) { $subject .= $chars[array_rand($chars)]; } $new = array("id" => $id++, "parent_id" => $p["id"], "subject" => $subject); $newnodes[] = $new; } $nodes = array_merge($nodes, $newnodes); } $start = microtime(true); $mem_start = memory_get_usage(); if (!phorum_ext_treesort($nodes, "id", "parent_id", 2, "subject", 10, 5, 1)) { die("Sort failed.\n"); } echo "Time: " . (microtime(true) - $start) . "\n"; echo "Mem: " . (memory_get_usage() - $mem_start) . "\n"; foreach ($nodes as $node) { if ($node["parent_id"] == 0) { print str_repeat("-", 50) . "\n"; } print str_repeat("-", $node["indent_cnt"]); print "{$node["id"]} \"{$node["subject"]}\"\n"; } print str_repeat("-", 50) . "\n";
function phorum_sort_threads($rows) { $PHORUM = $GLOBALS["PHORUM"]; if (count($rows) == 0) { return $rows; } // Get template defined settings values. $indentmultiplier = isset($PHORUM['TMP']['indentmultiplier']) ? $PHORUM['TMP']['indentmultiplier'] : 20; $cut_min = isset($PHORUM['TMP']['subject_cut_min']) ? $PHORUM['TMP']['subject_cut_min'] : 20; $cut_max = isset($PHORUM['TMP']['subject_cut_max']) ? $PHORUM['TMP']['subject_cut_max'] : 60; $cut_indentfactor = isset($PHORUM['TMP']['subject_cut_indentfactor']) ? $PHORUM['TMP']['subject_cut_indentfactor'] : 2; // ------------------------------------------------------------------ // Use the Phorum PHP extension if it is available // ------------------------------------------------------------------ if (!empty($PHORUM["php_phorum_extension"]) && function_exists('phorum_ext_treesort')) { phorum_ext_treesort($rows, "message_id", "parent_id", $indentmultiplier, "subject", $cut_min, $cut_max, $cut_indentfactor); return $rows; } // ------------------------------------------------------------------ // PHP extension not available. Revert to the pure PHP solution. // ------------------------------------------------------------------ $missing_parents = array(); foreach ($rows as $row) { // add row for this message with its parent $tmp_rows[$row["message_id"]]["parent_id"] = $row["parent_id"]; // check if this row was thought to be missing and undo that if (isset($missing_parents[$row["message_id"]])) { unset($missing_parents[$row["message_id"]]); } // if this row's parent is not yet set, mark it missing // when it is encountered, it will be removed if ($row["parent_id"] != 0 && empty($tmp_rows[$row["parent_id"]])) { $missing_parents[$row["parent_id"]] = $row["parent_id"]; } // add this row to the parents child list $tmp_rows[$row["parent_id"]]["children"][] = $row["message_id"]; } // ------------------------------------------------------------------ // If there are missing parent, promote their children to the top // This should be the exception for broken data // ------------------------------------------------------------------ if (!empty($missing_parents)) { foreach ($missing_parents as $parent_id) { foreach ($tmp_rows[$parent_id]["children"] as $child) { $tmp_rows[$child]["parent_id"] = 0; $tmp_rows[0]["children"][] = $child; } unset($tmp_rows[$parent_id]); } } $order = array(); $stack = array(); $curr_id = 0; while (count($tmp_rows)) { if (empty($seen[$curr_id])) { if ($curr_id != 0) { $seen[$curr_id] = true; $order[$curr_id] = $rows[$curr_id]; unset($rows[$curr_id]); $indent = count($stack) - 1; // new style of indenting by padding-left $order[$curr_id]["indent_cnt"] = $indent * $indentmultiplier; // Break up long words in the subject. $cut_len = $cut_max - $indent * $cut_indentfactor; if ($cut_len < $cut_min) { $cut_len = $cut_min; } $order[$curr_id]["subject"] = wordwrap($order[$curr_id]["subject"], $cut_len, " ", TRUE); } } array_push($stack, $curr_id); $data = $tmp_rows[$curr_id]; if (isset($data["children"])) { if (count($data["children"])) { $curr_id = array_shift($tmp_rows[$curr_id]["children"]); } else { unset($tmp_rows[$curr_id]); array_pop($stack); $curr_id = array_pop($stack); } } else { unset($tmp_rows[$curr_id]); array_pop($stack); if (count($tmp_rows[$data["parent_id"]]["children"])) { $curr_id = array_shift($tmp_rows[$data["parent_id"]]["children"]); } else { unset($tmp_rows[$data["parent_id"]]); array_pop($stack); $curr_id = array_pop($stack); } } } return $order; }