diff --git a/lib/bst_array.php b/lib/bst_array.php
new file mode 100644
index 000000000..9e41f3c5f
--- /dev/null
+++ b/lib/bst_array.php
@@ -0,0 +1,149 @@
+<?php
+/**
+ * SeekQuarry/Yioop --
+ * Open Source Pure PHP Search Engine, Crawler, and Indexer
+ *
+ * Copyright (C) 2009, 2010 Chris Pollett chris@pollett.org
+ *
+ * LICENSE:
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * END LICENSE
+ *
+ * @author Chris Pollett chris@pollett.org
+ * @package seek_quarry
+ * @subpackage library
+ * @license http://www.gnu.org/licenses/ GPL3
+ * @link http://www.seekquarry.com/
+ * @copyright 2009, 2010
+ * @filesource
+ */
+if(!defined('BASE_DIR')) {echo "BAD REQUEST"; exit();}
+
+/**
+ * Load charCopy
+ */
+require_once "utility.php";
+
+/**
+ *
+ * @author Chris Pollett
+ *
+ * @package seek_quarry
+ * @subpackage library
+ */
+
+class BSTArray
+{
+ var $data;
+ var $data_len;
+ var $key_len;
+ var $value_len;
+ var $entry_len;
+ var $key_compare;
+
+ /**
+ *
+ */
+ function __construct($key_len, $value_len, $key_compare)
+ {
+ $this->data = "";
+ $this->data_len = 0;
+ $this->key_len = $key_len;
+ $this->value_len = $value_len;
+ $this->entry_len = $key_len + $value_len + 8;
+ $this->key_compare = $key_compare;
+ }
+
+ /**
+ *
+ */
+ function insertUpdate($key, $value)
+ {
+ $key_compare = $this->key_compare;
+ if($this->contains($key, $offset, $parent_offset))
+ {
+ list(, , $left_offset, $right_offset) = $this->readEntry($offset);
+ charCopy($key . $value . pack("N",$left_offset) .
+ pack("N", $right_offset),$this->data, $offset,$this->entry_len);
+ } else {
+ if($parent_offset != $offset) { // data already exists
+ list($parent_key, $parent_value, $parent_left_offset,
+ $parent_right_offset) = $this->readEntry($parent_offset);
+ if($key_compare($parent_key, $key) < 0 ) {
+ $parent_right_offset = $offset;
+ } else {
+ $parent_left_offset = $offset;
+ }
+ $new_parent_entry = $parent_key . $parent_value .
+ pack("N", $parent_left_offset) .
+ pack("N", $parent_right_offset);
+ charCopy( $new_parent_entry,
+ $this->data, $parent_offset, $this->entry_len);
+ }
+ $this->data .= $key . $value . pack("H*", "7FFFFFFF7FFFFFFF");
+ $this->data_len += $this->entry_len;
+ }
+ }
+
+ /**
+ *
+ */
+ function contains($key, &$offset, &$parent_offset)
+ {
+ $offset = 0;
+ $parent_offset = 0;
+ $data_len = $this->data_len;
+ $entry_len = $this->entry_len;
+ $last_entry = $data_len - $entry_len;
+ $key_compare = $this->key_compare;
+ while($offset <= $last_entry ) {
+ list($cur_key, , $left_offset, $right_offset) =
+ $this->readEntry($offset);
+ $comparison = $key_compare($cur_key, $key);
+ if($comparison == 0) {
+ return true;
+ } else if ($comparison < 0) {
+ $parent_offset = $offset;
+ $offset = $right_offset;
+ } else {
+ $parent_offset = $offset;
+ $offset = $left_offset;
+ }
+ }
+
+ $offset = $data_len;
+ return false;
+ }
+
+ /**
+ *
+ */
+ function readEntry($offset)
+ {
+ $key = substr($this->data, $offset, $this->key_len);
+ $offset += $this->key_len;
+ $value = substr($this->data, $offset, $this->value_len);
+ $offset += $this->value_len;
+ $left_string = substr($this->data, $offset, 4);
+ $tmp = unpack("N", $left_string);
+ $left_offset = $tmp[1];
+ $offset += 4;
+ $right_string = substr($this->data, $offset, 4);
+ $tmp = unpack("N", $right_string);
+ $right_offset = $tmp[1];
+ return array($key, $value, $left_offset, $right_offset);
+ }
+}
diff --git a/tests/bst_array_test.php b/tests/bst_array_test.php
new file mode 100644
index 000000000..5c545e4d2
--- /dev/null
+++ b/tests/bst_array_test.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * SeekQuarry/Yioop --
+ * Open Source Pure PHP Search Engine, Crawler, and Indexer
+ *
+ * Copyright (C) 2009, 2010 Chris Pollett chris@pollett.org
+ *
+ * LICENSE:
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * END LICENSE
+ *
+ * @author Chris Pollett chris@pollett.org
+ * @package seek_quarry
+ * @subpackage test
+ * @license http://www.gnu.org/licenses/ GPL3
+ * @link http://www.seekquarry.com/
+ * @copyright 2009, 2010
+ * @filesource
+ */
+
+if(!defined('BASE_DIR')) {echo "BAD REQUEST"; exit();}
+
+/**
+ * Load the string_array library we'll be testing
+ */
+require_once BASE_DIR."/lib/bst_array.php";
+
+/**
+ * Used to test that the BSTArray class properly stores/retrieves values,
+ *
+ * @author Chris Pollett
+ * @package seek_quarry
+ * @subpackage test
+ */
+class BSTArrayTest extends UnitTest
+{
+ /**
+ * We'll use two different tables one more representative of how the table
+ * is going to be used by the web_queue_bundle, the other small enough that
+ * we can manually figure out what the result should be
+ */
+ public function setUp()
+ {
+ $this->test_objects['BST'] = new BSTArray(1, 1, "strcmp");
+ }
+
+ /**
+ */
+ public function tearDown()
+ {
+ unset($this->test_objects['BST']);
+ }
+
+ /**
+ * Check if can put objects into BST array and retrieve them
+ */
+ public function insertTestCase()
+ {
+ $this->test_objects['BST']->insertUpdate(chr(65), chr(66));
+ $flag = $this->test_objects['BST']->contains(chr(65), $offset, $parent);
+ $this->assertTrue($flag, "BST contains what was just inserted");
+ $this->test_objects['BST']->insertUpdate(chr(67), chr(68));
+ $flag = $this->test_objects['BST']->contains(chr(67), $offset, $parent);
+ $this->assertTrue($flag, "BST contains second insert");
+ $this->test_objects['BST']->insertUpdate(chr(66), chr(69));
+ $flag = $this->test_objects['BST']->contains(chr(66), $offset, $parent);
+ $this->assertTrue($flag, "BST contains third insert");
+ $this->test_objects['BST']->insertUpdate(chr(69), chr(69));
+ $flag = $this->test_objects['BST']->contains(chr(69), $offset, $parent);
+ $this->assertTrue($flag, "BST contains fourth insert");
+ }
+
+ /**
+ * Check if can modify objects in BST array
+ */
+ public function updateTestCase()
+ {
+ $this->test_objects['BST']->insertUpdate(chr(65), chr(66));
+ $this->test_objects['BST']->insertUpdate(chr(67), chr(68));
+ $this->test_objects['BST']->insertUpdate(chr(66), chr(69));
+ $this->test_objects['BST']->insertUpdate(chr(69), chr(69));
+ $this->test_objects['BST']->insertUpdate(chr(66), chr(66));
+ $this->test_objects['BST']->contains(chr(66), $offset, $parent);
+ list($key, $value, $left, $right) = $this->test_objects['BST']->
+ readEntry($offset);
+ $this->assertEqual($value, chr(66), "BST contains fourth insert");
+ }
+
+}
+?>
diff --git a/tests/index_shard_test.php b/tests/index_shard_test.php
new file mode 100644
index 000000000..e95ece531
--- /dev/null
+++ b/tests/index_shard_test.php
@@ -0,0 +1,367 @@
+<?php
+/**
+ * SeekQuarry/Yioop --
+ * Open Source Pure PHP Search Engine, Crawler, and Indexer
+ *
+ * Copyright (C) 2009, 2010 Chris Pollett chris@pollett.org
+ *
+ * LICENSE:
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * END LICENSE
+ *
+ * @author Chris Pollett chris@pollett.org
+ * @package seek_quarry
+ * @subpackage test
+ * @license http://www.gnu.org/licenses/ GPL3
+ * @link http://www.seekquarry.com/
+ * @copyright 2009, 2010
+ * @filesource
+ */
+
+if(!defined('BASE_DIR')) {echo "BAD REQUEST"; exit();}
+
+/**
+ * Load the library for crawlHash
+ */
+require_once BASE_DIR."/lib/utility.php";
+
+/**
+ * Load the library for crawlHash
+ */
+require_once BASE_DIR."/lib/crawl_constants.php";
+
+
+/**
+ * Load the index_shard library we'll be testing
+ */
+require_once BASE_DIR."/lib/index_shard.php";
+
+
+/**
+ * Used to test that the StringArray class properly stores/retrieves values,
+ * and can handle loading and saving
+ *
+ * @author Chris Pollett
+ * @package seek_quarry
+ * @subpackage test
+ */
+class IndexShardTest extends UnitTest
+{
+ /**
+ *
+ */
+ public function setUp()
+ {
+ $this->test_objects['shard'] = new IndexShard("shard.txt", 0);
+ $this->test_objects['shard2'] = new IndexShard("shard2.txt", 0);
+ }
+
+ /**
+ *
+ */
+ public function tearDown()
+ {
+ @unlink("shard.txt");
+ @unlink("shard2.txt");
+ }
+
+ /**
+ * Check if can store documents into an index shard and retrieve them
+ */
+ public function addDocumentsGetWordSliceByIdTestCase()
+ {
+ $docid = "AAAAAAAA";
+ $offset = 5;
+ $word_counts = array(
+ 'BBBBBBBB' => 1,
+ 'CCCCCCCC' => 2,
+ 'DDDDDDDD' => 6,
+ );
+
+ $meta_ids = array(
+ "EEEEEEEE",
+ "FFFFFFFF"
+ );
+
+ $this->test_objects['shard']->addDocumentWords($docid,
+ $offset, $word_counts, $meta_ids);
+ $this->assertEqual($this->test_objects['shard']->len_all_docs, 9,
+ "Len All Docs Correctly Counts Length of First Doc");
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('CCCCCCCC', true), 5);
+ $this->assertTrue(isset($c_data["AAAAAAAA"]),
+ "Doc lookup by word works");
+ // add a second document and check
+ $docid = "HHHHHHHH";
+ $offset = 7;
+ $word_counts = array(
+ 'CCCCCCCC' => 9,
+ 'GGGGGGGG' => 6,
+ );
+ $meta_ids = array(
+ "YYYYYYYY"
+ );
+ $this->test_objects['shard']->addDocumentWords($docid,
+ $offset, $word_counts, $meta_ids);
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('CCCCCCCC', true), 5);
+
+ $this->assertTrue(isset($c_data["AAAAAAAA"]),
+ "Work lookup first item of two works");
+ $this->assertTrue(isset($c_data["HHHHHHHH"]),
+ "Work lookup second item of two works");
+ $this->assertEqual(count($c_data), 2,
+ "Exactly two items were found in two item case");
+
+ //add a meta word lookup
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('EEEEEEEE', true), 5);
+ $this->assertTrue(isset($c_data["AAAAAAAA"]),
+ "Doc lookup by meta word works");
+ $this->assertEqual(count($c_data), 1,
+ "Doc lookup by meta word works has correct count");
+ }
+
+ /**
+ * Check if can store link documents into an index shard and retrieve them
+ */
+ public function addLinkGetWordSliceByIdTestCase()
+ {
+ $docid = "AAAAAAAA:BBBBBBBB:CCCCCCCC"; //set up link doc
+ $offset = 5;
+ $word_counts = array(
+ 'MMMMMMMM' => 1,
+ 'NNNNNNNN' => 2,
+ 'OOOOOOOO' => 6,
+ );
+
+ $meta_ids = array(
+ "PPPPPPPP",
+ "QQQQQQQQ"
+ );
+
+ $this->test_objects['shard']->addDocumentWords($docid,
+ $offset, $word_counts, $meta_ids);
+ $this->assertEqual($this->test_objects['shard']->len_all_link_docs, 9,
+ "Len All Docs Correctly Counts Length of First Doc");
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('MMMMMMMM', true), 5);
+ $this->assertTrue(isset($c_data["AAAAAAAA:BBBBBBBB:CCCCCCCC"]),
+ "Link Doc lookup by word works");
+ $docid = "AAAAAAAA";
+ $offset = 10;
+ $word_counts = array(
+ 'BBBBBBBB' => 1,
+ 'CCCCCCCC' => 2,
+ 'MMMMMMMM' => 6,
+ );
+
+ $meta_ids = array(
+ "EEEEEEEE",
+ "FFFFFFFF"
+ );
+
+ $this->test_objects['shard']->addDocumentWords($docid,
+ $offset, $word_counts, $meta_ids);
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('MMMMMMMM', true), 5);
+ $this->assertTrue(isset($c_data["AAAAAAAA:BBBBBBBB:CCCCCCCC"]),
+ "Link Doc lookup by word works 1st of two");
+ $this->assertTrue(isset($c_data["AAAAAAAA"]),
+ "Link Doc lookup by word works 2nd doc");
+ $this->assertEqual(count($c_data), 2,
+ "Link Doc lookup by word works has correct count");
+ }
+
+ /**
+ * Check that appending two index shards works correctly
+ */
+ public function appendIndexShardTestCase()
+ {
+ $docid = "AAAAAAAA";
+ $offset = 5;
+ $word_counts = array(
+ 'BBBBBBBB' => 1,
+ 'CCCCCCCC' => 2,
+ 'DDDDDDDD' => 6,
+ );
+
+ $meta_ids = array(
+ "EEEEEEEE",
+ "FFFFFFFF"
+ );
+ $this->test_objects['shard']->addDocumentWords($docid,
+ $offset, $word_counts, $meta_ids);
+
+ $docid = "KKKKKKKK:GGGGGGGG:HHHHHHHH";
+ $offset = 20;
+ $word_counts = array(
+ 'ZZZZZZZZ' => 9,
+ 'DDDDDDDD' => 4,
+ );
+ $meta_ids = array(
+ );
+ $this->test_objects['shard2']->addDocumentWords($docid,
+ $offset, $word_counts, $meta_ids);
+ $docid = "GGGGGGGG";
+ $offset = 6;
+ $word_counts = array(
+ 'DDDDDDDD' => 3,
+ 'IIIIIIII' => 4,
+ 'JJJJJJJJ' => 5,
+ );
+
+ $meta_ids = array(
+ "KKKKKKKK"
+ );
+ $this->test_objects['shard2']->addDocumentWords($docid,
+ $offset, $word_counts, $meta_ids);
+ $this->test_objects['shard']->appendIndexShard(
+ $this->test_objects['shard2']);
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('BBBBBBBB', true), 5);
+ $this->assertTrue(isset($c_data["AAAAAAAA"]),
+ "Data from first shard present 1");
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('CCCCCCCC', true), 5);
+ $this->assertTrue(isset($c_data["AAAAAAAA"]),
+ "Data from first shard present 2");
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('DDDDDDDD', true), 5);
+ $this->assertTrue(isset($c_data["AAAAAAAA"]),
+ "Data from first shard present 3");
+ $this->assertTrue(isset($c_data["KKKKKKKK:GGGGGGGG:HHHHHHHH"]),
+ "Data from second shard present 1");
+ $this->assertTrue(isset($c_data["GGGGGGGG"]),
+ "Data from third shard present 1");
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('EEEEEEEE', true), 5);
+ $this->assertTrue(isset($c_data["AAAAAAAA"]),
+ "Data from first shard present 4");
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('FFFFFFFF', true), 5);
+ $this->assertTrue(isset($c_data["AAAAAAAA"]),
+ "Data from first shard present 5");
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('ZZZZZZZZ', true), 5);
+ $this->assertTrue(isset($c_data["KKKKKKKK:GGGGGGGG:HHHHHHHH"]),
+ "Data from second shard present 2");
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('IIIIIIII', true), 5);
+ $this->assertTrue(isset($c_data["GGGGGGGG"]),
+ "Data from third shard present 2");
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('JJJJJJJJ', true), 5);
+ $this->assertTrue(isset($c_data["GGGGGGGG"]),
+ "Data from third shard present 3");
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('KKKKKKKK', true), 5);
+ $this->assertTrue(isset($c_data["GGGGGGGG"]),
+ "Data from third shard present 4");
+ }
+
+ /**
+ * Check that changing document offsets works
+ */
+ public function changeDocumentOffsetTestCase()
+ {
+ $docid = "AAAAAAAA";
+ $offset = 0;
+ $word_counts = array(
+ 'BBBBBBBB' => 1
+ );
+
+ $meta_ids = array(
+ );
+ $this->test_objects['shard']->addDocumentWords($docid,
+ $offset, $word_counts, $meta_ids);
+ $docid = "AAAAAAAA:EEEEEEEE:FFFFFFFF";
+ $offset = 0;
+ $word_counts = array(
+ 'BBBBBBBB' => 1
+ );
+ $meta_ids = array(
+ );
+ $this->test_objects['shard']->addDocumentWords($docid,
+ $offset, $word_counts, $meta_ids);
+ $docid = "QQQQQQQQ:EEEEEEEE:FFFFFFFF";
+ $offset = 0;
+ $word_counts = array(
+ 'BBBBBBBB' => 1
+ );
+ $meta_ids = array(
+ );
+ $this->test_objects['shard']->addDocumentWords($docid,
+ $offset, $word_counts, $meta_ids);
+ $docid = "DDDDDDDD";
+ $offset = 0;
+ $word_counts = array(
+ 'BBBBBBBB' => 1
+ );
+ $meta_ids = array(
+ );
+ $this->test_objects['shard']->addDocumentWords($docid,
+ $offset, $word_counts, $meta_ids);
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('BBBBBBBB', true), 5);
+ $new_doc_offsets = array(
+ "AAAAAAAA" => 5,
+ "CCCCCCCC" => 6,
+ "QQQQQQQQ:EEEEEEEE:FFFFFFFF" => 9,
+ "DDDDDDDD" => 7,
+ );
+ $this->test_objects['shard']->changeDocumentOffsets($new_doc_offsets);
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('BBBBBBBB', true), 5);
+ $predicted_offsets = array(
+ "AAAAAAAA" => 5,
+ "AAAAAAAA:EEEEEEEE:FFFFFFFF" => 0,
+ "QQQQQQQQ:EEEEEEEE:FFFFFFFF" => 9,
+ "DDDDDDDD" => 7,
+ );
+ $i = 0;
+ foreach($predicted_offsets as $key =>$offset) {
+ $this->assertTrue(isset($c_data[$key]), "Summary key matches predicted $i");
+ $this->assertEqual($c_data[$key][CrawlConstants::SUMMARY_OFFSET],
+ $offset, "Summary offset matches predicted $i");
+ $i++;
+ }
+ }
+
+ /**
+ * Check the code for calculating word document relaevance computes
+ * correct values
+ */
+ public function checkRelevanceCalculationTestCase()
+ {
+ }
+
+ /**
+ *
+ */
+ public function markDuplicatesTestCase()
+ {
+ $doc_urls = array("http://somewhere.com/");
+
+ $this->test_objects['shard']->markDuplicateDocs($doc_urls);
+ $c_data = $this->test_objects['shard']->getWordSliceById(
+ crawlHash('info:http://somewhere.com/', true), 5);
+ $this->assertTrue(isset(
+ $c_data[crawlHash($doc_urls[0], true)][CrawlConstants::DUPLICATE]),
+ "Duplicate data shows up as duplicate");
+ }
+}
+?>
diff --git a/tests/string_cat_experiment.php b/tests/string_cat_experiment.php
new file mode 100644
index 000000000..da2f3441e
--- /dev/null
+++ b/tests/string_cat_experiment.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * SeekQuarry/Yioop --
+ * Open Source Pure PHP Search Engine, Crawler, and Indexer
+ *
+ * Copyright (C) 2009, 2010 Chris Pollett chris@pollett.org
+ *
+ * LICENSE:
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * END LICENSE
+ *
+ * Test to see for big strings which how long various string concatenation
+ * operations take.
+ *
+ * @author Chris Pollett chris@pollett.org
+ * @package seek_quarry
+ * @subpackage test
+ * @license http://www.gnu.org/licenses/ GPL3
+ * @link http://www.seekquarry.com/
+ * @copyright 2009, 2010
+ * @filesource
+ */
+
+if(isset($_SERVER['DOCUMENT_ROOT']) && strlen($_SERVER['DOCUMENT_ROOT']) > 0) {
+ echo "BAD REQUEST";
+ exit();
+}
+
+ini_set("memory_limit","300M");
+echo "Time to pack null strings of various lengths with pack('xLEN')\n";
+
+for($i = 10; $i< 100000000; $i *= 10) {
+ $start = microtime();
+ $big_string = pack("x$i");
+ echo "Len = $i Time =".changeInMicroTime($start)."secs \n";
+}
+
+echo 'Concatenation $str2 = $str1.$str1 where $str1 of various lengths'."\n";
+for($i = 10; $i< 100000000; $i *= 10) {
+ $big_string = pack("x$i");
+ $start = microtime();
+ $str2 = $big_string.$big_string;
+ echo "Len = $i Time =".changeInMicroTime($start)."secs \n";
+}
+
+unset($str2);
+
+echo 'Concatenation $str1 .= $str1 where $str1 of various lengths'."\n";
+for($i = 10; $i< 100000000; $i *= 10) {
+ $big_string = pack("x$i");
+ $start = microtime();
+ $big_string .= $big_string;
+ echo "Len = $i Time =".changeInMicroTime($start)."secs \n";
+}
+
+echo 'Time to concatenate "hello" on to a string of various lengths'."\n";
+for($i = 10; $i< 100000000; $i *= 10) {
+ $big_string = pack("x$i");
+ $start = microtime();
+ $big_string .= "hello";
+ echo "Len = $i Time =".changeInMicroTime($start)."secs \n";
+}
+
+echo "Concatenate hello various numbers of times to a string of length 10^7\n";
+
+for($i = 10; $i< 10000000; $i *= 10) {
+ $big_string = pack("x100000000");
+ $start = microtime();
+ for($j = 0; $j < $i; $j++) {
+ $big_string .= "hello";
+ }
+ echo "Num Hello Cats = $i Time =".changeInMicroTime($start)."secs \n";
+}
+
+function changeInMicrotime( $start, $end=NULL )
+{
+ if( !$end ) {
+ $end= microtime();
+ }
+ list($start_microseconds, $start_seconds) = explode(" ", $start);
+ list($end_microseconds, $end_seconds) = explode(" ", $end);
+
+ $change_in_seconds = intval($end_seconds) - intval($start_seconds);
+ $change_in_microseconds =
+ floatval($end_microseconds) - floatval($start_microseconds);
+
+ return floatval( $change_in_seconds ) + $change_in_microseconds;
+}
+
+?>