From 66bec9475dcd888482382128867f08a70709def4 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Tue, 4 Oct 2016 03:51:13 +0000 Subject: [PATCH 1/6] Improved queries for the nodeinfo functionality and the admin page --- mod/admin.php | 27 ++++++++++++++++++--------- mod/nodeinfo.php | 11 +++++++++-- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/mod/admin.php b/mod/admin.php index 4dc6064a7d..2856c16401 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -1277,14 +1277,14 @@ function admin_page_users(&$a){ /* ordering */ $valid_orders = array( - 'contact.name', + 'contact.name', 'user.email', 'user.register_date', 'user.login_date', - 'lastitem.lastitem_date', + 'lastitem_date', 'user.page-flags' ); - + $order = "contact.name"; $order_direction = "+"; if (x($_GET,'o')){ @@ -1293,19 +1293,18 @@ function admin_page_users(&$a){ $order_direction = "-"; $new_order = substr($new_order,1); } - + if (in_array($new_order, $valid_orders)){ $order = $new_order; } if (x($_GET,'d')){ $new_direction = $_GET['d']; - } } $sql_order = "`".str_replace('.','`.`',$order)."`"; $sql_order_direction = ($order_direction==="+")?"ASC":"DESC"; - - $users = q("SELECT `user`.* , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired` + +/* $users = q("SELECT `user`.* , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired` FROM (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid` FROM `item` @@ -1322,9 +1321,19 @@ function admin_page_users(&$a){ intval($a->pager['start']), intval($a->pager['itemspage']) ); - +*/ + $users = q("SELECT `user`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`account_expired`, + (SELECT `changed` FROM `item` WHERE `wall` AND `uid` = `user`.`uid` ORDER BY `changed` DESC LIMIT 1) AS `lastitem_date` + FROM `user` + INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self` + WHERE `user`.`verified` + ORDER BY $sql_order $sql_order_direction LIMIT %d, %d", + intval($a->pager['start']), + intval($a->pager['itemspage']) + ); + //echo "
$users"; killme();
-				
+
 	$adminlist = explode(",", str_replace(" ", "", $a->config['admin_email']));
 	$_setup_users = function ($e) use ($adminlist){
 		$accounts = array(
diff --git a/mod/nodeinfo.php b/mod/nodeinfo.php
index ba310a1051..fae2b10522 100644
--- a/mod/nodeinfo.php
+++ b/mod/nodeinfo.php
@@ -184,7 +184,7 @@ function nodeinfo_cron() {
 		}
 	}
         logger("cron_start");
-
+/*
 	$users = q("SELECT profile.*, `user`.`login_date`, `lastitem`.`lastitem_date`
 			FROM (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
 				FROM `item`
@@ -198,7 +198,14 @@ function nodeinfo_cron() {
 					AND NOT `user`.`blocked`
 					AND NOT `user`.`account_removed`
 					AND NOT `user`.`account_expired`");
-
+*/
+	$users = q("SELECT `user`.`uid`, `user`.`login_date`,
+			(SELECT `changed` FROM `item` WHERE `wall` AND `uid` = `user`.`uid` ORDER BY `changed` DESC LIMIT 1) AS `lastitem_date`
+			FROM `user`
+			INNER JOIN `profile` ON `profile`.`uid` = `user`.`uid` AND `profile`.`is-default`
+			WHERE (`profile`.`publish` OR `profile`.`net-publish`) AND `user`.`verified`
+				AND NOT `user`.`blocked` AND NOT `user`.`account_removed`
+				AND NOT `user`.`account_expired`");
 	if (is_array($users)) {
 			$total_users = count($users);
 			$active_users_halfyear = 0;

From 5fb2e4780967cc549447a997fbac6e37196d329b Mon Sep 17 00:00:00 2001
From: Michael Vogel 
Date: Wed, 5 Oct 2016 16:12:53 +0000
Subject: [PATCH 2/6] Increased performance when storing items

---
 include/items.php   | 15 ++++++++++
 include/threads.php |  4 +++
 mod/item.php        | 68 ++++++++++++++++++++++++++++++++++++---------
 3 files changed, 74 insertions(+), 13 deletions(-)

diff --git a/include/items.php b/include/items.php
index 6d2c830f96..0871d0bf81 100644
--- a/include/items.php
+++ b/include/items.php
@@ -370,6 +370,13 @@ function uri_to_guid($uri) {
 
 function item_store($arr,$force_parent = false, $notify = false, $dontcache = false) {
 
+        $perfdb   = $a->performance["database"];
+        $perfdbw  = $a->performance["database_write"];
+        $perfnet  = $a->performance["network"];
+        $perffile = $a->performance["file"];
+
+	logger("Performance: Start", LOGGER_DEBUG);
+
 	// If it is a posting where users should get notifications, then define it as wall posting
 	if ($notify) {
 		$arr['wall'] = 1;
@@ -914,6 +921,14 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
 		add_shadow_entry($arr);
 	}
 
+        $perfdb   = $a->performance["database"] - $perfdb;
+        $perfdbw  = $a->performance["database_write"] - $perfdbw;
+        $perfnet  = $a->performance["network"] - $perfnet;
+        $perffile = $a->performance["file"] - $perffile;
+
+        logger("Performance: DB-R: ".round($perfdb - $perfdbw, 2)." - DB-W: ".round($perfdbw, 2)." - Net: ".round($perfnet, 2)." - File: ".round($perffile, 2), LOGGER_DEBUG);
+        //logger("Performance: DB-R: ".round($perfdb - $perfdbw, 2)." - DB-W: ".round($perfdbw, 2)." - Net: ".round($perfnet, 2), LOGGER_DEBUG);
+
 	check_item_notification($current_post, $uid);
 
 	if ($notify)
diff --git a/include/threads.php b/include/threads.php
index 2e02e7ada3..e9002fe66e 100644
--- a/include/threads.php
+++ b/include/threads.php
@@ -135,7 +135,9 @@ function update_thread($itemid, $setmention = false) {
 			$sql .= "`".$field."` = '".dbesc($data)."'";
 		}
 
+	logger("Pre Update Thread", LOGGER_DEBUG);
 	$result = q("UPDATE `thread` SET ".$sql." WHERE `iid` = %d", intval($itemid));
+	logger("Post Update Thread", LOGGER_DEBUG);
 
 	logger("Update thread for item ".$itemid." - guid ".$item["guid"]." - ".print_r($result, true)." ".print_r($item, true), LOGGER_DEBUG);
 
@@ -145,6 +147,7 @@ function update_thread($itemid, $setmention = false) {
 	if (!$items)
 		return;
 
+	logger("Pre Update Item", LOGGER_DEBUG);
 	$result = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `rendered-html` = '%s', `rendered-hash` = '%s' WHERE `id` = %d",
 			dbesc($item["title"]),
 			dbesc($item["body"]),
@@ -152,6 +155,7 @@ function update_thread($itemid, $setmention = false) {
 			dbesc($item["rendered-hash"]),
 			intval($items[0]["id"])
 		);
+	logger("Post Update Item", LOGGER_DEBUG);
 	logger("Updating public shadow for post ".$items[0]["id"]." - guid ".$item["guid"]." Result: ".print_r($result, true), LOGGER_DEBUG);
 }
 
diff --git a/mod/item.php b/mod/item.php
index 9a9b5895bd..28ce1e0047 100644
--- a/mod/item.php
+++ b/mod/item.php
@@ -29,6 +29,13 @@ require_once('include/Contact.php');
 
 function item_post(&$a) {
 
+	$perfdb   = $a->performance["database"];
+	$perfdbw  = $a->performance["database_write"];
+	$perfnet  = $a->performance["network"];
+	$perffile = $a->performance["file"];
+
+	logger("Performance: Start", LOGGER_DEBUG);
+
 	if((! local_user()) && (! remote_user()) && (! x($_REQUEST,'commenter')))
 		return;
 
@@ -460,7 +467,7 @@ function item_post(&$a) {
 				if(! count($r))
 					continue;
 
-
+				logger("Pre Photo", LOGGER_DEBUG);
 				$r = q("UPDATE `photo` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s'
 					WHERE `resource-id` = '%s' AND `uid` = %d AND `album` = '%s' ",
 					dbesc($str_contact_allow),
@@ -471,6 +478,7 @@ function item_post(&$a) {
 					intval($profile_uid),
 					dbesc( t('Wall Photos'))
 				);
+				logger("Post Photo", LOGGER_DEBUG);
 
 			}
 		}
@@ -492,6 +500,7 @@ function item_post(&$a) {
 					intval($attach)
 				);
 				if(count($r)) {
+					logger("Pre Attach", LOGGER_DEBUG);
 					$r = q("UPDATE `attach` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s'
 						WHERE `uid` = %d AND `id` = %d",
 						dbesc($str_contact_allow),
@@ -501,6 +510,7 @@ function item_post(&$a) {
 						intval($profile_uid),
 						intval($attach)
 					);
+					logger("Post Attach", LOGGER_DEBUG);
 				}
 			}
 		}
@@ -762,6 +772,7 @@ function item_post(&$a) {
 	put_item_in_cache($datarray);
 
 	if($orig_post) {
+		logger("Pre Update", LOGGER_DEBUG);
 		$r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `attach` = '%s', `file` = '%s', `rendered-html` = '%s', `rendered-hash` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d",
 			dbesc($datarray['title']),
 			dbesc($datarray['body']),
@@ -775,6 +786,7 @@ function item_post(&$a) {
 			intval($post_id),
 			intval($profile_uid)
 		);
+		logger("Post Update", LOGGER_DEBUG);
 
 		create_tags_from_item($post_id);
 		create_files_from_item($post_id);
@@ -793,7 +805,17 @@ function item_post(&$a) {
 	else
 		$post_id = 0;
 
+	if ($parent) {
+		// Inherit ACLs from the parent item.
+		/// @todo Check if really needed
+		$datarray['allow_cid'] = $parent_item['allow_cid'];
+		$datarray['allow_gid'] = $parent_item['allow_gid'];
+		$datarray['deny_cid'] = $parent_item['deny_cid'];
+		$datarray['deny_gid'] = $parent_item['deny_gid'];
+		$datarray['private'] = $parent_item['private'];
+	}
 
+	logger("Pre Insert", LOGGER_DEBUG);
 	$r = q("INSERT INTO `item` (`guid`, `extid`, `uid`,`type`,`wall`,`gravity`, `network`, `contact-id`,
 					`owner-name`,`owner-link`,`owner-avatar`, `owner-id`,
 					`author-name`, `author-link`, `author-avatar`, `author-id`,
@@ -860,6 +882,8 @@ function item_post(&$a) {
 		dbesc($datarray['rendered-hash'])
 	       );
 
+	logger("Post Insert", LOGGER_DEBUG);
+
 	$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1",
 		dbesc($datarray['uri']));
 	if(!count($r)) {
@@ -880,15 +904,18 @@ function item_post(&$a) {
 
 	if($parent) {
 
+		logger("Pre Update last-child", LOGGER_DEBUG);
 		// This item is the last leaf and gets the comment box, clear any ancestors
-		$r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent` = %d ",
+		$r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent` = %d AND `last-child`",
 			dbesc(datetime_convert()),
 			intval($parent)
 		);
-		update_thread($parent, true);
+		logger("Post Update last-child", LOGGER_DEBUG);
+		//Test: update_thread($parent, true);
 
 		// Inherit ACLs from the parent item.
-
+/*
+		logger("Pre Update ACL", LOGGER_DEBUG);
 		$r = q("UPDATE `item` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `private` = %d
 			WHERE `id` = %d",
 			dbesc($parent_item['allow_cid']),
@@ -898,7 +925,8 @@ function item_post(&$a) {
 			intval($parent_item['private']),
 			intval($post_id)
 		);
-
+		logger("Post Update ACL", LOGGER_DEBUG);
+*/
 		if($contact_record != $author) {
 			notification(array(
 				'type'         => NOTIFY_COMMENT,
@@ -951,6 +979,7 @@ function item_post(&$a) {
 	if(! $parent)
 		$parent = $post_id;
 
+	logger("Pre Update Parent", LOGGER_DEBUG);
 	$r = q("UPDATE `item` SET `parent` = %d, `parent-uri` = '%s', `plink` = '%s', `changed` = '%s', `last-child` = 1, `visible` = 1
 		WHERE `id` = %d",
 		intval($parent),
@@ -959,27 +988,32 @@ function item_post(&$a) {
 		dbesc(datetime_convert()),
 		intval($post_id)
 	);
+	logger("Pre Update Parent", LOGGER_DEBUG);
 
 	// photo comments turn the corresponding item visible to the profile wall
 	// This way we don't see every picture in your new photo album posted to your wall at once.
 	// They will show up as people comment on them.
 
-	if(! $parent_item['visible']) {
-		$r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d",
-			intval($parent_item['id'])
-		);
-		update_thread($parent_item['id']);
-	}
+	//if(! $parent_item['visible']) {
+	//	logger("Pre Update Visible", LOGGER_DEBUG);
+	//	$r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d",
+	//		intval($parent_item['id'])
+	//	);
+	//	logger("Post Update Visible", LOGGER_DEBUG);
+		//update_thread($parent_item['id']);
+	//}
 
 	// update the commented timestamp on the parent
 
-	q("UPDATE `item` set `commented` = '%s', `changed` = '%s' WHERE `id` = %d",
+	logger("Pre Update Commented", LOGGER_DEBUG);
+	q("UPDATE `item` SET `visible` = 1, `commented` = '%s', `changed` = '%s' WHERE `id` = %d",
 		dbesc(datetime_convert()),
 		dbesc(datetime_convert()),
 		intval($parent)
 	);
+	logger("Post Update Commented", LOGGER_DEBUG);
 	if ($post_id != $parent)
-		update_thread($parent);
+		update_thread($parent, true);
 
 	call_hooks('post_local_end', $datarray);
 
@@ -1036,6 +1070,14 @@ function item_post(&$a) {
 
 	logger('post_complete');
 
+	$perfdb   = $a->performance["database"] - $perfdb;
+	$perfdbw  = $a->performance["database_write"] - $perfdbw;
+	$perfnet  = $a->performance["network"] - $perfnet;
+	$perffile = $a->performance["file"] - $perffile;
+
+	logger("Performance: DB-R: ".round($perfdb - $perfdbw, 2)." - DB-W: ".round($perfdbw, 2)." - Net: ".round($perfnet, 2)." - File: ".round($perffile, 2), LOGGER_DEBUG);
+	//logger("Performance: DB-R: ".round($perfdb - $perfdbw, 2)." - DB-W: ".round($perfdbw, 2)." - Net: ".round($perfnet, 2), LOGGER_DEBUG);
+
 	item_post_return($a->get_baseurl(), $api_source, $return_path);
 	// NOTREACHED
 }

From f9b9ee6b775ed5d76ef1a7b8870f83e164b4572c Mon Sep 17 00:00:00 2001
From: Michael Vogel 
Date: Thu, 6 Oct 2016 21:24:29 +0000
Subject: [PATCH 3/6] Increased performance when storing items

---
 mod/item.php | 153 +++++++++++++++------------------------------------
 1 file changed, 44 insertions(+), 109 deletions(-)

diff --git a/mod/item.php b/mod/item.php
index 28ce1e0047..093842db5c 100644
--- a/mod/item.php
+++ b/mod/item.php
@@ -29,13 +29,6 @@ require_once('include/Contact.php');
 
 function item_post(&$a) {
 
-	$perfdb   = $a->performance["database"];
-	$perfdbw  = $a->performance["database_write"];
-	$perfnet  = $a->performance["network"];
-	$perffile = $a->performance["file"];
-
-	logger("Performance: Start", LOGGER_DEBUG);
-
 	if((! local_user()) && (! remote_user()) && (! x($_REQUEST,'commenter')))
 		return;
 
@@ -299,7 +292,6 @@ function item_post(&$a) {
 		// If this is a comment, set the permissions from the parent.
 
 		if($parent_item) {
-			$private = 0;
 
 			// for non native networks use the network of the original post as network of the item
 			if (($parent_item['network'] != NETWORK_DIASPORA)
@@ -307,19 +299,13 @@ function item_post(&$a) {
 				AND ($network == ""))
 				$network = $parent_item['network'];
 
-			if(($parent_item['private'])
-				|| strlen($parent_item['allow_cid'])
-				|| strlen($parent_item['allow_gid'])
-				|| strlen($parent_item['deny_cid'])
-				|| strlen($parent_item['deny_gid'])) {
-				$private = (($parent_item['private']) ? $parent_item['private'] : 1);
-			}
-
 			$str_contact_allow = $parent_item['allow_cid'];
 			$str_group_allow   = $parent_item['allow_gid'];
 			$str_contact_deny  = $parent_item['deny_cid'];
 			$str_group_deny    = $parent_item['deny_gid'];
+			$private           = $parent_item['private'];
 		}
+
 		$pubmail_enable    = ((x($_REQUEST,'pubmail_enable') && intval($_REQUEST['pubmail_enable']) && (! $private)) ? 1 : 0);
 
 		// if using the API, we won't see pubmail_enable - figure out if it should be set
@@ -467,7 +453,6 @@ function item_post(&$a) {
 				if(! count($r))
 					continue;
 
-				logger("Pre Photo", LOGGER_DEBUG);
 				$r = q("UPDATE `photo` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s'
 					WHERE `resource-id` = '%s' AND `uid` = %d AND `album` = '%s' ",
 					dbesc($str_contact_allow),
@@ -478,8 +463,6 @@ function item_post(&$a) {
 					intval($profile_uid),
 					dbesc( t('Wall Photos'))
 				);
-				logger("Post Photo", LOGGER_DEBUG);
-
 			}
 		}
 	}
@@ -500,7 +483,6 @@ function item_post(&$a) {
 					intval($attach)
 				);
 				if(count($r)) {
-					logger("Pre Attach", LOGGER_DEBUG);
 					$r = q("UPDATE `attach` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s'
 						WHERE `uid` = %d AND `id` = %d",
 						dbesc($str_contact_allow),
@@ -510,7 +492,6 @@ function item_post(&$a) {
 						intval($profile_uid),
 						intval($attach)
 					);
-					logger("Post Attach", LOGGER_DEBUG);
 				}
 			}
 		}
@@ -735,6 +716,11 @@ function item_post(&$a) {
 	$datarray['self']          = $self;
 //	$datarray['prvnets']       = $user['prvnets'];
 
+	$datarray['parent-uri'] = ($parent == 0) ? $uri : $parent_item['uri'];
+	$datarray['plink'] = $a->get_baseurl().'/display/'.urlencode($datarray['guid']);
+	$datarray['last-child'] = 1;
+	$datarray['visible'] = 1;
+
 	if($orig_post)
 		$datarray['edit']      = true;
 
@@ -772,7 +758,6 @@ function item_post(&$a) {
 	put_item_in_cache($datarray);
 
 	if($orig_post) {
-		logger("Pre Update", LOGGER_DEBUG);
 		$r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `attach` = '%s', `file` = '%s', `rendered-html` = '%s', `rendered-hash` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d",
 			dbesc($datarray['title']),
 			dbesc($datarray['body']),
@@ -786,7 +771,6 @@ function item_post(&$a) {
 			intval($post_id),
 			intval($profile_uid)
 		);
-		logger("Post Update", LOGGER_DEBUG);
 
 		create_tags_from_item($post_id);
 		create_files_from_item($post_id);
@@ -801,21 +785,9 @@ function item_post(&$a) {
 			goaway($a->get_baseurl() . "/" . $return_path );
 		}
 		killme();
-	}
-	else
+	} else
 		$post_id = 0;
 
-	if ($parent) {
-		// Inherit ACLs from the parent item.
-		/// @todo Check if really needed
-		$datarray['allow_cid'] = $parent_item['allow_cid'];
-		$datarray['allow_gid'] = $parent_item['allow_gid'];
-		$datarray['deny_cid'] = $parent_item['deny_cid'];
-		$datarray['deny_gid'] = $parent_item['deny_gid'];
-		$datarray['private'] = $parent_item['private'];
-	}
-
-	logger("Pre Insert", LOGGER_DEBUG);
 	$r = q("INSERT INTO `item` (`guid`, `extid`, `uid`,`type`,`wall`,`gravity`, `network`, `contact-id`,
 					`owner-name`,`owner-link`,`owner-avatar`, `owner-id`,
 					`author-name`, `author-link`, `author-avatar`, `author-id`,
@@ -824,7 +796,8 @@ function item_post(&$a) {
 					`tag`, `inform`, `verb`, `object-type`, `postopts`,
 					`allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`, `private`,
 					`pubmail`, `attach`, `bookmark`,`origin`, `moderated`, `file`,
-					`rendered-html`, `rendered-hash`)
+					`rendered-html`, `rendered-hash`,
+					`parent`, `parent-uri`, `plink`, `last-child`, `visible`)
 		VALUES('%s', '%s', %d, '%s', %d, %d, '%s', %d,
 			'%s', '%s', '%s', %d,
 			'%s', '%s', '%s', %d,
@@ -833,7 +806,8 @@ function item_post(&$a) {
 			'%s', '%s', '%s', '%s', '%s',
 			'%s', '%s', '%s', '%s', %d,
 			%d, '%s', %d, %d, %d, '%s',
-			'%s', '%s')",
+			'%s', '%s',
+			%d, '%s', '%s', %d, %d)",
 		dbesc($datarray['guid']),
 		dbesc($datarray['extid']),
 		intval($datarray['uid']),
@@ -879,11 +853,14 @@ function item_post(&$a) {
 		intval($datarray['moderated']),
 		dbesc($datarray['file']),
 		dbesc($datarray['rendered-html']),
-		dbesc($datarray['rendered-hash'])
+		dbesc($datarray['rendered-hash']),
+		intval($datarray['parent']),
+		dbesc($datarray['parent-uri']),
+		dbesc($datarray['plink']),
+		intval($datarray['last-child']),
+		intval($datarray['visible'])
 	       );
 
-	logger("Post Insert", LOGGER_DEBUG);
-
 	$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1",
 		dbesc($datarray['uri']));
 	if(!count($r)) {
@@ -897,36 +874,26 @@ function item_post(&$a) {
 	logger('mod_item: saved item ' . $post_id);
 
 	$datarray["id"] = $post_id;
-	$datarray["plink"] = $a->get_baseurl().'/display/'.urlencode($datarray["guid"]);
 
 	// update filetags in pconfig
 	file_tag_update_pconfig($uid,$categories_old,$categories_new,'category');
 
 	if($parent) {
 
-		logger("Pre Update last-child", LOGGER_DEBUG);
 		// This item is the last leaf and gets the comment box, clear any ancestors
-		$r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent` = %d AND `last-child`",
+		$r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent` = %d AND `last-child` AND `id` != %d",
+			dbesc(datetime_convert()),
+			intval($parent),
+			intval($post_id)
+		);
+
+		// update the commented timestamp on the parent
+		q("UPDATE `item` SET `visible` = 1, `commented` = '%s', `changed` = '%s' WHERE `id` = %d",
+			dbesc(datetime_convert()),
 			dbesc(datetime_convert()),
 			intval($parent)
 		);
-		logger("Post Update last-child", LOGGER_DEBUG);
-		//Test: update_thread($parent, true);
 
-		// Inherit ACLs from the parent item.
-/*
-		logger("Pre Update ACL", LOGGER_DEBUG);
-		$r = q("UPDATE `item` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `private` = %d
-			WHERE `id` = %d",
-			dbesc($parent_item['allow_cid']),
-			dbesc($parent_item['allow_gid']),
-			dbesc($parent_item['deny_cid']),
-			dbesc($parent_item['deny_gid']),
-			intval($parent_item['private']),
-			intval($post_id)
-		);
-		logger("Post Update ACL", LOGGER_DEBUG);
-*/
 		if($contact_record != $author) {
 			notification(array(
 				'type'         => NOTIFY_COMMENT,
@@ -955,6 +922,10 @@ function item_post(&$a) {
 	} else {
 		$parent = $post_id;
 
+		$r = q("UPDATE `item` SET `parent` = %d WHERE `id` = %d",
+			intval($parent),
+			intval($post_id));
+
 		if($contact_record != $author) {
 			notification(array(
 				'type'         => NOTIFY_WALL,
@@ -974,47 +945,6 @@ function item_post(&$a) {
 		}
 	}
 
-	// fallback so that parent always gets set to non-zero.
-
-	if(! $parent)
-		$parent = $post_id;
-
-	logger("Pre Update Parent", LOGGER_DEBUG);
-	$r = q("UPDATE `item` SET `parent` = %d, `parent-uri` = '%s', `plink` = '%s', `changed` = '%s', `last-child` = 1, `visible` = 1
-		WHERE `id` = %d",
-		intval($parent),
-		dbesc(($parent == $post_id) ? $uri : $parent_item['uri']),
-		dbesc($a->get_baseurl().'/display/'.urlencode($datarray['guid'])),
-		dbesc(datetime_convert()),
-		intval($post_id)
-	);
-	logger("Pre Update Parent", LOGGER_DEBUG);
-
-	// photo comments turn the corresponding item visible to the profile wall
-	// This way we don't see every picture in your new photo album posted to your wall at once.
-	// They will show up as people comment on them.
-
-	//if(! $parent_item['visible']) {
-	//	logger("Pre Update Visible", LOGGER_DEBUG);
-	//	$r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d",
-	//		intval($parent_item['id'])
-	//	);
-	//	logger("Post Update Visible", LOGGER_DEBUG);
-		//update_thread($parent_item['id']);
-	//}
-
-	// update the commented timestamp on the parent
-
-	logger("Pre Update Commented", LOGGER_DEBUG);
-	q("UPDATE `item` SET `visible` = 1, `commented` = '%s', `changed` = '%s' WHERE `id` = %d",
-		dbesc(datetime_convert()),
-		dbesc(datetime_convert()),
-		intval($parent)
-	);
-	logger("Post Update Commented", LOGGER_DEBUG);
-	if ($post_id != $parent)
-		update_thread($parent, true);
-
 	call_hooks('post_local_end', $datarray);
 
 	if(strlen($emailcc) && $profile_uid == local_user()) {
@@ -1056,6 +986,19 @@ function item_post(&$a) {
 
 	if ($post_id == $parent)
 		add_thread($post_id);
+	else {
+		update_thread($parent, true);
+		unset($datarray['self']);
+		unset($datarray['wall']);
+		unset($datarray['origin']);
+
+		if (in_array($datarray['type'], array("net-comment", "wall-comment", "remote-comment")))
+			$datarray['type'] = 'remote-comment';
+		else
+			unset($datarray['type']);
+
+		add_shadow_entry($datarray);
+	}
 
 	// This is a real juggling act on shared hosting services which kill your processes
 	// e.g. dreamhost. We used to start delivery to our native delivery agents in the background
@@ -1070,14 +1013,6 @@ function item_post(&$a) {
 
 	logger('post_complete');
 
-	$perfdb   = $a->performance["database"] - $perfdb;
-	$perfdbw  = $a->performance["database_write"] - $perfdbw;
-	$perfnet  = $a->performance["network"] - $perfnet;
-	$perffile = $a->performance["file"] - $perffile;
-
-	logger("Performance: DB-R: ".round($perfdb - $perfdbw, 2)." - DB-W: ".round($perfdbw, 2)." - Net: ".round($perfnet, 2)." - File: ".round($perffile, 2), LOGGER_DEBUG);
-	//logger("Performance: DB-R: ".round($perfdb - $perfdbw, 2)." - DB-W: ".round($perfdbw, 2)." - Net: ".round($perfnet, 2), LOGGER_DEBUG);
-
 	item_post_return($a->get_baseurl(), $api_source, $return_path);
 	// NOTREACHED
 }

From 6abac720e238c4be601836cb0f8199f3bb6a817a Mon Sep 17 00:00:00 2001
From: Michael Vogel 
Date: Fri, 7 Oct 2016 06:05:43 +0000
Subject: [PATCH 4/6] Small performance tweaks for "item_store" as well.

---
 include/items.php  | 74 +++++++++++++++++++++-------------------------
 include/poller.php |  8 +++++
 mod/item.php       | 10 +++++--
 3 files changed, 49 insertions(+), 43 deletions(-)

diff --git a/include/items.php b/include/items.php
index 0871d0bf81..5f0187ad97 100644
--- a/include/items.php
+++ b/include/items.php
@@ -370,13 +370,6 @@ function uri_to_guid($uri) {
 
 function item_store($arr,$force_parent = false, $notify = false, $dontcache = false) {
 
-        $perfdb   = $a->performance["database"];
-        $perfdbw  = $a->performance["database_write"];
-        $perfnet  = $a->performance["network"];
-        $perffile = $a->performance["file"];
-
-	logger("Performance: Start", LOGGER_DEBUG);
-
 	// If it is a posting where users should get notifications, then define it as wall posting
 	if ($notify) {
 		$arr['wall'] = 1;
@@ -676,7 +669,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
 
 			// If its a post from myself then tag the thread as "mention"
 			logger("item_store: Checking if parent ".$parent_id." has to be tagged as mention for user ".$arr['uid'], LOGGER_DEBUG);
-			$u = q("select * from user where uid = %d limit 1", intval($arr['uid']));
+			$u = q("SELECT `nickname` FROM `user` WHERE `uid` = %d", intval($arr['uid']));
 			if(count($u)) {
 				$a = get_app();
 				$self = normalise_link($a->get_baseurl() . '/profile/' . $u[0]['nickname']);
@@ -686,8 +679,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
 					logger("item_store: tagged thread ".$parent_id." as mention for user ".$self, LOGGER_DEBUG);
 				}
 			}
-		}
-		else {
+		} else {
 
 			// Allow one to see reply tweets from status.net even when
 			// we don't have or can't see the original post.
@@ -742,6 +734,19 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
 		$arr["global"] = (count($isglobal) > 0);
 	}
 
+	// ACL settings
+	if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid))
+		$private = 1;
+	else
+		$private = $arr['private'];
+
+	$arr["allow_cid"] = $allow_cid;
+	$arr["allow_gid"] = $allow_gid;
+	$arr["deny_cid"] = $deny_cid;
+	$arr["deny_gid"] = $deny_gid;
+	$arr["private"] = $private;
+	$arr["deleted"] = $parent_deleted;
+
 	// Fill the cache field
 	put_item_in_cache($arr);
 
@@ -814,41 +819,38 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
 				dbesc($arr['received']),
 				intval($arr['contact-id'])
 			);
+
+		// Now do the same for the system wide contacts with uid=0
+		if (!$arr['private']) {
+			q("UPDATE `contact` SET `success_update` = '%s', `last-item` = '%s' WHERE `id` = %d",
+				dbesc($arr['received']),
+				dbesc($arr['received']),
+				intval($arr['owner-id'])
+			);
+
+			if ($arr['owner-id'] != $arr['author-id'])
+				q("UPDATE `contact` SET `success_update` = '%s', `last-item` = '%s' WHERE `id` = %d",
+					dbesc($arr['received']),
+					dbesc($arr['received']),
+					intval($arr['author-id'])
+				);
+		}
 	} else {
 		logger('item_store: could not locate created item');
 		return 0;
 	}
 
-	if((! $parent_id) || ($arr['parent-uri'] === $arr['uri']))
+	if(!$parent_id || ($arr['parent-uri'] === $arr['uri']))
 		$parent_id = $current_post;
 
-	if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid))
-		$private = 1;
-	else
-		$private = $arr['private'];
-
-	// Set parent id - and also make sure to inherit the parent's ACLs.
-
-	$r = q("UPDATE `item` SET `parent` = %d, `allow_cid` = '%s', `allow_gid` = '%s',
-		`deny_cid` = '%s', `deny_gid` = '%s', `private` = %d, `deleted` = %d WHERE `id` = %d",
+	// Set parent id
+	$r = q("UPDATE `item` SET `parent` = %d WHERE `id` = %d",
 		intval($parent_id),
-		dbesc($allow_cid),
-		dbesc($allow_gid),
-		dbesc($deny_cid),
-		dbesc($deny_gid),
-		intval($private),
-		intval($parent_deleted),
 		intval($current_post)
 	);
 
 	$arr['id'] = $current_post;
 	$arr['parent'] = $parent_id;
-	$arr['allow_cid'] = $allow_cid;
-	$arr['allow_gid'] = $allow_gid;
-	$arr['deny_cid'] = $deny_cid;
-	$arr['deny_gid'] = $deny_gid;
-	$arr['private'] = $private;
-	$arr['deleted'] = $parent_deleted;
 
 	// update the commented timestamp on the parent
 	// Only update "commented" if it is really a comment
@@ -921,14 +923,6 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
 		add_shadow_entry($arr);
 	}
 
-        $perfdb   = $a->performance["database"] - $perfdb;
-        $perfdbw  = $a->performance["database_write"] - $perfdbw;
-        $perfnet  = $a->performance["network"] - $perfnet;
-        $perffile = $a->performance["file"] - $perffile;
-
-        logger("Performance: DB-R: ".round($perfdb - $perfdbw, 2)." - DB-W: ".round($perfdbw, 2)." - Net: ".round($perfnet, 2)." - File: ".round($perffile, 2), LOGGER_DEBUG);
-        //logger("Performance: DB-R: ".round($perfdb - $perfdbw, 2)." - DB-W: ".round($perfdbw, 2)." - Net: ".round($perfnet, 2), LOGGER_DEBUG);
-
 	check_item_notification($current_post, $uid);
 
 	if ($notify)
diff --git a/include/poller.php b/include/poller.php
index fe4d4245af..61ec89e597 100644
--- a/include/poller.php
+++ b/include/poller.php
@@ -128,8 +128,16 @@ function poller_run(&$argv, &$argc){
 
 		if (function_exists($funcname)) {
 			logger("Process ".$mypid." - Prio ".$r[0]["priority"]." - ID ".$r[0]["id"].": ".$funcname." ".$r[0]["parameter"]);
+
+			// For better logging create a new process id for every worker call
+			// But preserve the old one for the worker
+			$old_process_id = $a->process_id;
+			$a->process_id = uniqid("wrk", true);
+
 			$funcname($argv, $argc);
 
+			$a->process_id = $old_process_id;
+
 			if ($cooldown > 0) {
 				logger("Process ".$mypid." - Prio ".$r[0]["priority"]." - ID ".$r[0]["id"].": ".$funcname." - in cooldown for ".$cooldown." seconds");
 				sleep($cooldown);
diff --git a/mod/item.php b/mod/item.php
index 093842db5c..e9056d08cc 100644
--- a/mod/item.php
+++ b/mod/item.php
@@ -988,14 +988,18 @@ function item_post(&$a) {
 		add_thread($post_id);
 	else {
 		update_thread($parent, true);
+
+		// Insert an item entry for UID=0 for global entries
+		// We have to remove or change some data before that,
+		// so that the post appear like a regular received post.
 		unset($datarray['self']);
 		unset($datarray['wall']);
 		unset($datarray['origin']);
 
-		if (in_array($datarray['type'], array("net-comment", "wall-comment", "remote-comment")))
+		if (in_array($datarray['type'], array("net-comment", "wall-comment")))
 			$datarray['type'] = 'remote-comment';
-		else
-			unset($datarray['type']);
+		elseif ($datarray['type'] == 'wall')
+			$datarray['type'] = 'remote';
 
 		add_shadow_entry($datarray);
 	}

From 94f7debb520e260958a51e3312101ae621151431 Mon Sep 17 00:00:00 2001
From: Michael Vogel 
Date: Fri, 7 Oct 2016 11:08:36 +0000
Subject: [PATCH 5/6] Loglines removed

---
 include/threads.php | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/include/threads.php b/include/threads.php
index e9002fe66e..2e02e7ada3 100644
--- a/include/threads.php
+++ b/include/threads.php
@@ -135,9 +135,7 @@ function update_thread($itemid, $setmention = false) {
 			$sql .= "`".$field."` = '".dbesc($data)."'";
 		}
 
-	logger("Pre Update Thread", LOGGER_DEBUG);
 	$result = q("UPDATE `thread` SET ".$sql." WHERE `iid` = %d", intval($itemid));
-	logger("Post Update Thread", LOGGER_DEBUG);
 
 	logger("Update thread for item ".$itemid." - guid ".$item["guid"]." - ".print_r($result, true)." ".print_r($item, true), LOGGER_DEBUG);
 
@@ -147,7 +145,6 @@ function update_thread($itemid, $setmention = false) {
 	if (!$items)
 		return;
 
-	logger("Pre Update Item", LOGGER_DEBUG);
 	$result = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `rendered-html` = '%s', `rendered-hash` = '%s' WHERE `id` = %d",
 			dbesc($item["title"]),
 			dbesc($item["body"]),
@@ -155,7 +152,6 @@ function update_thread($itemid, $setmention = false) {
 			dbesc($item["rendered-hash"]),
 			intval($items[0]["id"])
 		);
-	logger("Post Update Item", LOGGER_DEBUG);
 	logger("Updating public shadow for post ".$items[0]["id"]." - guid ".$item["guid"]." Result: ".print_r($result, true), LOGGER_DEBUG);
 }
 

From b70676d2314bb9310d3f39857d982309f36bbc09 Mon Sep 17 00:00:00 2001
From: Michael Vogel 
Date: Fri, 7 Oct 2016 21:07:21 +0000
Subject: [PATCH 6/6] Optimized query for nodeinfo and admin user page

---
 mod/admin.php    | 20 +-------------------
 mod/nodeinfo.php | 18 ++----------------
 2 files changed, 3 insertions(+), 35 deletions(-)

diff --git a/mod/admin.php b/mod/admin.php
index b11faa39ac..c9ff23e2d8 100644
--- a/mod/admin.php
+++ b/mod/admin.php
@@ -1306,26 +1306,8 @@ function admin_page_users(&$a){
 	$sql_order = "`".str_replace('.','`.`',$order)."`";
 	$sql_order_direction = ($order_direction==="+")?"ASC":"DESC";
 
-/*	$users = q("SELECT `user`.* , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
-				FROM
-					(SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
-					FROM `item`
-					WHERE `item`.`type` = 'wall'
-					GROUP BY `item`.`uid`) AS `lastitem`
-						 RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
-					   `contact`
-				WHERE
-					   `user`.`uid` = `contact`.`uid`
-						AND `user`.`verified` =1
-					AND `contact`.`self` =1
-				ORDER BY $sql_order $sql_order_direction LIMIT %d, %d
-				",
-				intval($a->pager['start']),
-				intval($a->pager['itemspage'])
-				);
-*/
 	$users = q("SELECT `user`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`account_expired`,
-				(SELECT `changed` FROM `item` WHERE `wall` AND `uid` = `user`.`uid` ORDER BY `changed` DESC LIMIT 1) AS `lastitem_date`
+				(SELECT MAX(`changed`) FROM `item` FORCE INDEX (`uid_wall_changed`) WHERE `wall` AND `uid` = `user`.`uid`) AS `lastitem_date`
 				FROM `user`
 				INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`
 				WHERE `user`.`verified`
diff --git a/mod/nodeinfo.php b/mod/nodeinfo.php
index fae2b10522..585659e5cb 100644
--- a/mod/nodeinfo.php
+++ b/mod/nodeinfo.php
@@ -184,23 +184,9 @@ function nodeinfo_cron() {
 		}
 	}
         logger("cron_start");
-/*
-	$users = q("SELECT profile.*, `user`.`login_date`, `lastitem`.`lastitem_date`
-			FROM (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
-				FROM `item`
-					WHERE `item`.`type` = 'wall'
-						GROUP BY `item`.`uid`) AS `lastitem`
-						RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`, `contact`, `profile`
-                                WHERE
-					`user`.`uid` = `contact`.`uid` AND `profile`.`uid` = `user`.`uid`
-					AND `profile`.`is-default` AND (`profile`.`publish` OR `profile`.`net-publish`)
-					AND `user`.`verified` AND `contact`.`self`
-					AND NOT `user`.`blocked`
-					AND NOT `user`.`account_removed`
-					AND NOT `user`.`account_expired`");
-*/
+
 	$users = q("SELECT `user`.`uid`, `user`.`login_date`,
-			(SELECT `changed` FROM `item` WHERE `wall` AND `uid` = `user`.`uid` ORDER BY `changed` DESC LIMIT 1) AS `lastitem_date`
+			(SELECT MAX(`changed`) FROM `item` FORCE INDEX (`uid_wall_changed`) WHERE `wall` AND `uid` = `user`.`uid`) AS `lastitem_date`
 			FROM `user`
 			INNER JOIN `profile` ON `profile`.`uid` = `user`.`uid` AND `profile`.`is-default`
 			WHERE (`profile`.`publish` OR `profile`.`net-publish`) AND `user`.`verified`