diff --git a/checkin_notes b/checkin_notes
index 7f6b1d9570..667379493d 100755
--- a/checkin_notes
+++ b/checkin_notes
@@ -13297,3 +13297,21 @@ Charlie 21 Oct 2005
mac_build/
boinc.pbproj/
project.pbxproj
+
+David 22 Oct 2005
+ - Prevent the "merge host" feature from being used
+ to merge distinct hosts
+ (and create host records with exaggerated credit totals).
+ Hosts X and Y are considered "compatible" (for merging)
+ only if X.rpc_time < Y.create_time or vice-versa.
+ - When merging hosts X and Y,
+ a) decay their expavg_credit prior to adding and updating
+ b) set create_time to the min of the two
+ c) if the target is older, update its rpc_time and rpc_seqno
+
+ html/
+ inc/
+ host.inc
+ user/
+ host_edit_action.php
+ host_edit_form.php
diff --git a/html/inc/host.inc b/html/inc/host.inc
index 5404f02059..e7ed3ddc83 100644
--- a/html/inc/host.inc
+++ b/html/inc/host.inc
@@ -248,6 +248,9 @@ function ghz($x) {
}
}
+// return true if it's possible that the two host records
+// correspond to the same host
+//
function hosts_compatible($host1, $host2) {
// we screwed around with Intel processor names,
// so count them as compatible if both contain "Intel" and "Pentium",
@@ -266,7 +269,12 @@ function hosts_compatible($host1, $host2) {
if ($host2->p_model != $host1->p_model) return false;
}
if ($host2->os_name != $host1->os_name) return false;
- return true;
+
+ // one host must strictly precede the other
+ //
+ if ($host1.rpc_time < $host2.create_time) return true;
+ if ($host2.rpc_time < $host1.create_time) return true;
+ return false;
}
// recompute host's average credit by scanning results.
diff --git a/html/user/host_edit_action.php b/html/user/host_edit_action.php
index e820efc887..cca1daec68 100644
--- a/html/user/host_edit_action.php
+++ b/html/user/host_edit_action.php
@@ -27,14 +27,21 @@ function merge_hosts($old_host, $new_host) {
echo "
Merging host $old_host->id into host $new_host->id\n";
+ // decay the average credit of both hosts
+ //
+ $now = time();
+ update_average($now, 0, 0, $old_host->expavg_credit, $old_host->expavg_time);
+ update_average($now, 0, 0, $new_host->expavg_credit, $new_host->expavg_time);
+
// update the database:
// - add credit from old to new host
// - change results to refer to new host
+ // - update create and RPC times
// - put old host in "zombie" state
//
$total_credit = $old_host->total_credit + $new_host->total_credit;
$recent_credit = $old_host->expavg_credit + $new_host->expavg_credit;
- $result = mysql_query("update host set total_credit=$total_credit, expavg_credit=$recent_credit where id=$new_host->id");
+ $result = mysql_query("update host set total_credit=$total_credit, expavg_credit=$recent_credit, $expavg_time=$now where id=$new_host->id");
if (!$result) {
fail("Couldn't update credit of new computer");
}
@@ -42,42 +49,57 @@ function merge_hosts($old_host, $new_host) {
if (!$result) {
fail("Couldn't update results");
}
+
+ if ($old_host->rpc_time < $new_host->create_time) {
+ $query = "update host set create_time=$old_host->create_time where id=$new_host->id";
+ $result = mysql_query($query);
+ if (!$result) {
+ fail("Couldn't update times");
+ }
+ }
+ if ($new_host->rpc_time < $old_host->create_time) {
+ $query = "update host set rpc_time=$old_host->rpc_time, rpc_seqno=$old_host->rpc_seqno where id=$new_host->id";
+ $result = mysql_query($query);
+ if (!$result) {
+ fail("Couldn't update times");
+ }
+ }
$result = mysql_query("update host set total_credit=0, expavg_credit=0, userid=0, rpc_seqno=$new_host->id where id=$old_host->id");
if (!$result) {
- fail("Couldn't update old computer");
+ fail("Couldn't retire old computer");
}
echo "
Retired old computer $old_host->id\n";
}
- db_init();
- $user = get_logged_in_user();
+db_init();
+$user = get_logged_in_user();
- page_head("Merge computer records");
+page_head("Merge computer records");
- $nhosts = $_GET["nhosts"];
- $hostid = $_GET["id_0"];
- $latest_host = get_host($hostid, $user);
- for ($i=1; $i<$nhosts; $i++) {
- $var = "id_$i";
- $hostid = $_GET[$var];
- if (!$hostid) continue;
- $host = get_host($hostid, $user);
- if ($host->create_time > $latest_host->create_time) {
- merge_hosts($latest_host, $host);
- $latest_host = $host;
- } else {
- merge_hosts($host, $latest_host);
- }
- // reread latest_host from database since we just
- // updated its credits
- //
- $latest_host = lookup_host($latest_host->id);
- }
- echo "
-
Return to list of your computers - "; - page_tail(); +$nhosts = $_GET["nhosts"]; +$hostid = $_GET["id_0"]; +$latest_host = get_host($hostid, $user); +for ($i=1; $i<$nhosts; $i++) { + $var = "id_$i"; + $hostid = $_GET[$var]; + if (!$hostid) continue; + $host = get_host($hostid, $user); + if ($host->create_time > $latest_host->create_time) { + merge_hosts($latest_host, $host); + $latest_host = $host; + } else { + merge_hosts($host, $latest_host); + } + // reread latest_host from database since we just + // updated its credits + // + $latest_host = lookup_host($latest_host->id); +} +echo " +
Return to list of your computers +"; +page_tail(); - //Header("Location: show_host_detail.php?hostid=$latest_host->id"); +//Header("Location: show_host_detail.php?hostid=$latest_host->id"); ?> diff --git a/html/user/host_edit_form.php b/html/user/host_edit_form.php index 9ebf1ad152..6989447b69 100644 --- a/html/user/host_edit_form.php +++ b/html/user/host_edit_form.php @@ -33,7 +33,6 @@ start_table(); row_heading_array(array("", "name", "created", "computer ID")); while ($host2 = mysql_fetch_object($result)) { if ($host->id == $host2->id) continue; - //if ($host2->create_time > $host->create_time) continue; if (!hosts_compatible($host, $host2)) continue; $t = time_str($host2->create_time); $x = $host2->domain_name;