<?php

class FakePost {
	public function __construct($ID, $post_parent) {
		$this->ID = $ID;
		$this->post_parent = $post_parent;
	}
}


function get_page_children( $page_id, $pages ) {
	$post_hash = array();
	$children_hash = array();

	// build a hash of ID -> children
	foreach ( (array) $pages as $page ) {
		$post_hash[$page->ID] = $page;
		if ( !array_key_exists( $page->post_parent, $children_hash ) ) {
			$children_hash[$page->post_parent] = [$page->ID];
		} else {
			$children_hash[$page->post_parent][] = $page->ID;
		}
	}

	if( array_key_exists( $page_id, $children_hash ) ) {
		$post_list = array();
		$to_look = array_reverse( $children_hash[$page_id] );
		// while we still have posts to_look add them to the list
		while ( $to_look ) {
			$id = array_pop( $to_look );
			$post_list[] = $post_hash[$id];
			if ( array_key_exists( $id, $children_hash ) ) {
				foreach( array_reverse( $children_hash[$id] ) as $child ) {
					$to_look[] = $child;
				}
			}
		}
		return $post_list;
	} else {
		return array();
	}
}

function old_get_page_children($page_id, $pages) {
	$page_list = array();
	foreach ( (array) $pages as $page ) {
		if ( $page->post_parent == $page_id ) {
			$page_list[] = $page;
			if ( $children = old_get_page_children($page->ID, $pages) ) {
				$page_list = array_merge($page_list, $children);
			}
		}
	}
	return $page_list;
}

function tests() {
	$pages = [];
	$pages[] = new FakePost(1, 0);
	$pages[] = new FakePost(2, 0);
	$pages[] = new FakePost(3, 2);
	$pages[] = new FakePost(4, 2);
	$pages[] = new FakePost(5, 0);
	for ($i=6; $i < 1000; $i++) {
		$pages[] = new FakePost($i, rand(0, $i-1));
	}
	$max_depth = 50;
	for ($i=1000; $i < (1000 + $max_depth); $i++) {
		$pages[] = new FakePost($i, $i-1);
	}
	for ($i=(1000 + $max_depth); $i < 2000; $i++) {
		$pages[] = new FakePost($i, 5);
	}
	for ($i=2000; $i < 4000; $i++) {
		$pages[] = new FakePost($i, 1);
	}

	for ($i=0; $i < 8; $i++) {
		$time = [];
		$r = [];

		$time_start = microtime(true);
		$r[] = get_page_children($i, $pages);
		$time[] = (int) ((microtime(true) - $time_start) * 1000);

		$time_start = microtime(true);
		$r[] = old_get_page_children($i, $pages);
		$time[] = (int) ((microtime(true) - $time_start) * 1000);

		echo ($r[0] == $r[1])?'Equal':'Different';
		echo " $time[0] ms (new), $time[1] ms (old)\n";
	}
}

tests();
