return $formatted;
}
-//////////
+////////// just return a truncated text
function truncate ($text,$numb,$etc = "...") {
- if (strlen($text) > $numb) {
- $text = substr($text, 0, $numb);
- $text = $text.$etc;
- }
- return $text;
+ if (strlen($text) <= $numb) return $text;
+ return substr($text, 0, $numb).$etc;
+}
+// ditto but in case the text is too lare, returns a <span> with its 'title' set to the full value
+function truncate_and_popup ($text,$numb,$etc = "...") {
+ if (strlen($text) <= $numb) return $text;
+ $display=substr($text, 0, $numb).$etc;
+ return sprintf("<span title='%s'>%s</span>",$text,$display);
}
+
// generates <(atom) class=(class)> (text) </(atom)>
function html_atom ($atom,$text,$class="") {
$html="<$atom";
// shows a php variable verbatim with a heading message
function plc_debug ($message,$object) {
- print "<br>" . $message . "<pre>";
+ print "<br />" . $message . "<pre>";
print_r ($object);
print "</pre>";
}
+$plc_prof_start=0.;
+$plc_prof_time=0.;
+$plc_prof_counter=0;
+function plc_debug_prof_start () {
+ global $plc_prof_counter, $plc_prof_start, $plc_prof_time;
+ $plc_prof_counter=0;
+ plc_debug(strftime("[0] %T (start)") ,"heating up");
+ $plc_prof_time=microtime(true);
+ $plc_prof_start=$plc_prof_time;
+}
+function plc_debug_prof ($message,$object) {
+ global $plc_prof_counter, $plc_prof_start, $plc_prof_time;
+ $plc_prof_counter+=1;
+ $now=microtime(true);
+ $timelabel=strftime("%T");
+ $prof_message=sprintf("[%d] %s (%2.3f s -- %2.3f s) ",$plc_prof_counter,$timelabel,
+ ($now-$plc_prof_time),($now-$plc_prof_start));
+ plc_debug($prof_message.$message,$object);
+ $plc_prof_time=$now;
+}
+function plc_debug_prof_end () {
+ plc_debug_prof ("end","cooling down");
+}
+
if (! function_exists ("drupal_set_error")) {
function drupal_set_error ($text) {
drupal_set_message ("<span class=error>$text</span>");
if (count ($objs) == 0) $x=plc_warning_html($x . ' !!');
return $x;
}
+
+//////////////////// outlining reservable nodes
+$reservable_mark="-R-";
+$reservable_legend="reservable nodes are marked with " . $reservable_mark;
+
+
?>
var y_sep = 10;
// 1-grain leases attributes
-var x_grain = 24;
+var x_grain = 20;
var y_node = 15;
var radius= 6;
// vertical rules
var attr_rules={'fill':"#888", 'stroke-dasharray':'- ', 'stroke-width':0.5};
-var txt_timelabel = {"font": '"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif', stroke: "none", fill: "#008"};
+// set font-size separately in here rather than depend on the height
+var txt_timelabel = {"font": 'Times, "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif',
+ stroke: "none", fill: "#008", 'font-size': 9};
var txt_allnodes = {"font": '"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif', stroke: "none", fill: "#404"};
var txt_nodelabel = {"font": '"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif', stroke: "none", fill: "#008"};
var attr_timebutton = {'fill':'#bbf', 'stroke': '#338','stroke-width':2,
'stroke-linecap':'round', 'stroke-linejoin':'miter', 'stroke-miterlimit':3};
// keep consistent with sizes above - need for something nicer
-var timebutton_path = "M1,0L23,0L12,13L1,0";
+var timebutton_path = "M1,0L19,0L10,8L1,0";
/* lease dimensions and colors */
/* refrain from using gradient color, seems to not be animated properly */
col +=1;
// display time label
var timelabel=paper.text(left,y,timelabel).attr(txt_timelabel)
- .attr({"font-size":y_header, "text-anchor":"middle"});
+ .attr({"text-anchor":"middle"});
// draw vertical line
var path_spec="M"+left+" "+(y+y_header/2)+"L"+left+" "+this.total_height;
var rule=paper.path(path_spec).attr(attr_rules);
// -------------------- admins potentially need to get full list of users
ini_set('memory_limit','32M');
+$profiling=false;
+if ($_GET['profiling']) $profiling=true;
+
+if ($profiling) plc_debug_prof_start();
+
// --------------------
// recognized URL arguments
$slice_id=intval($_GET['id']);
$slice=$slices[0];
+if ($profiling) plc_debug_prof('2: slice',count($slices));
// pull all node info to vars
$name= $slice['name'];
$expires = date( "d/m/Y", $slice['expires'] );
$peers=new Peers ($api);
$local_peer = ! $peer_id;
+if ($profiling) plc_debug_prof('3: peers',count($peers));
+
// gets site info
$sites= $api->GetSites( array( $site_id ) );
$site=$sites[0];
$site_name= $site['name'];
$max_slices = $site['max_slices'];
+if ($profiling) plc_debug_prof('4: sites',count($sites));
//////////////////////////////////////// building blocks for the renew area
// Constants
global $DAY; $DAY = 24*60*60;
$tabs=array();
$tabs [] = tab_nodes_slice($slice_id);
-$tabs [] = tab_site($site_id);
+$tabs [] = tab_site($site);
// are these the right privileges for deletion ?
if ($privileges) {
$person_columns);
$count=count($persons);
+if ($profiling) plc_debug_prof('4: persons',count($persons));
$toggle=
new PlekitToggle ('my-slice-persons',"$count Users",
array('bubble'=>
$visibletags = new VisibleTags ($api, 'node');
$visiblecolumns = $visibletags->column_names();
$node_columns=array_merge($node_fixed_columns,$visiblecolumns);
-$nodes=$api->GetNodes(array('node_id'=>$slice['node_ids']),$node_columns);
-$potential_nodes=$api->GetNodes(array('~node_id'=>$slice['node_ids']),$node_columns);
-// reservable nodes: display only the ones in the slice to avoid confusion - also avoid an extra API call
-$reservable_nodes=array();
-foreach ($nodes as $node) { if ($node['node_type']=='reservable') $reservable_nodes[]=$node; }
-
-$reservable_mark="-R-";
-$reservable_legend="reservable nodes are marked with " . $reservable_mark;
+// optimizing calls to GetNodes
+$all_nodes=$api->GetNodes(NULL,$node_columns);
+//$slice_nodes=$api->GetNodes(array('node_id'=>$slice['node_ids']),$node_columns);
+//$potential_nodes=$api->GetNodes(array('~node_id'=>$slice['node_ids']),$node_columns);
+$slice_nodes=array();
+$potential_nodes=array();
+$reservable_nodes=array();
+foreach ($all_nodes as $node) {
+ if (in_array($node['node_id'],$slice['node_ids'])) {
+ $slice_nodes[]=$node;
+ if ($node['node_type']=='reservable') $reservable_nodes[]=$node;
+ } else {
+ $potential_nodes[]=$node;
+ }
+}
+if ($profiling) plc_debug_prof('5: nodes',count($slice_nodes));
////////////////////
// outline the number of reservable nodes
-$nodes_message=count_english($nodes,"node");
+$nodes_message=count_english($slice_nodes,"node");
if (count($reservable_nodes)) $nodes_message .= " (" . count($reservable_nodes) . " reservable)";
$toggle=new PlekitToggle ('my-slice-nodes',$nodes_message,
array('bubble'=>
//////////////////// nodes currently in
$toggle_nodes=new PlekitToggle('my-slice-nodes-current',
- count_english($nodes,"node") . " currently in $name",
+ count_english($slice_nodes,"node") . " currently in $name",
array('visible'=>get_arg('show_nodes_current',!$privileges)));
$toggle_nodes->start();
$form=new PlekitForm(l_actions(),array('slice_id'=>$slice['slice_id']));
$form->start();
$table->start();
-if ($nodes) foreach ($nodes as $node) {
+if ($slice_nodes) foreach ($slice_nodes as $node) {
$table->row_start();
$peers->cell($table,$node['peer_id']);
$table->cell(l_node_obj($node));
array('visible'=>get_arg('show_nodes_resa',false)));
$toggle_nodes->start();
$grain=$api->GetLeaseGranularity();
+ if ($profiling) plc_debug_prof('6 granul',$grain);
+ // where to start from, expressed as an offset in hours from now
+ $resa_offset=$_GET['resa_offset'];
+ if ( ! $resa_offset ) $resa_offset=0;
+ $rough_start=time()+$resa_offset*3600;
// xxx should be configurable
- $now=time();
- // xxx ditto,
+ $resa_slots=$_GET['resa_slots'];
+ if ( ! $resa_slots ) $resa_slots = 36;
// for now, show the next 72 hours, or 72 grains, which ever is smaller
- $duration=min(72*3600,72*$grain);
+ $duration=$resa_slots*$grain;
$steps=$duration/$grain;
- $start=intval($now/$grain)*$grain;
- $end=$now+$duration;
+ $start=intval($rough_start/$grain)*$grain;
+ $end=$rough_start+$duration;
$lease_columns=array('lease_id','name','t_from','t_until','hostname','name');
- $leases=$api->GetLeases(array(']t_until'=>$now,'[t_from'=>$end,'-SORT'=>'t_from'),$lease_columns);
+ $leases=$api->GetLeases(array(']t_until'=>$rough_start,'[t_from'=>$end,'-SORT'=>'t_from'),$lease_columns);
+ if ($profiling) plc_debug_prof('7 leases',count($leases));
// hash nodes -> leases
$host_hash=array();
foreach ($leases as $lease) {
}
# leases_data is the name used by leases.js to locate this table
echo "<table id='leases_data'>";
- # pass the slicename as the [0,0] coordinate as thead>tr>td
+ # pass (slice_id,slicename) as the [0,0] coordinate as thead>tr>td
echo "<thead><tr><td>" . $slice['slice_id'] . '&' . $slice['name'] . "</td>";
- for ($i=0; $i<$steps; $i++)
+ # the timeslot headers read (timestamp,label)
+ $day_names=array('Su','M','Tu','W','Th','F','Sa');
+ for ($i=0; $i<$steps; $i++) {
+ $timestamp=($start+$i*$grain);
+ $day=$day_names[intval(strftime("%w",$timestamp))];
+ $label=$day . strftime(" %H:%M",$timestamp);
// expose in each header cell the full timestamp, and how to display it - use & as a separator*/
- echo "<th>" . ($start+$i*$grain) . "&" . strftime("%H:%M",$start+$i*$grain). "</th>";
+ echo "<th>" . implode("&",array($timestamp,$label)) . "</th>";
+ }
echo "</tr></thead><tbody>";
// todo - sort on hostnames
function sort_hostname ($a,$b) { return ($a['hostname']<$b['hostname'])?-1:1;}
}
$toggle->end();
+// very wide values get abbreviated
+$tag_value_threshold=24;
//////////////////////////////////////////////////////////// Tags
//if ( $local_peer ) {
$tags=$api->GetSliceTags (array('slice_id'=>$slice_id));
+ if ($profiling) plc_debug_prof('8 slice tags',count($tags));
function get_tagname ($tag) { return $tag['tagname'];}
$tagnames = array_map ("get_tagname",$tags);
foreach ($tags as $tag) {
$node_name = "ALL";
if ($tag['node_id']) {
- $nodes = $api->GetNodes(array('node_id'=>$tag['node_id']));
- if($nodes) {
- $node = $nodes[0];
+ $tag_nodes = $api->GetNodes(array('node_id'=>$tag['node_id']));
+ if ($profiling) plc_debug_prof('9 node for slice tag',count($tag_nodes));
+ if($tag_nodes) {
+ $node = $tag_nodes[0];
$node_name = $node['hostname'];
}
}
$nodegroup_name="n/a";
if ($tag['nodegroup_id']) {
- $nodegroup=$api->GetNodeGroups(array('nodegroup_id'=>$tag['nodegroup_id']));
+ $nodegroups=$api->GetNodeGroups(array('nodegroup_id'=>$tag['nodegroup_id']));
+ if ($profiling) plc_debug_prof('10 nodegroup for slice tag',$nodegroup);
if ($nodegroup) {
- $nodegroup = $nodegroup[0];
+ $nodegroup = $nodegroups[0];
$nodegroup_name = $nodegroup['groupname'];
}
}
$table->row_start();
$table->cell(l_tag_obj($tag));
- $table->cell($tag['value']);
+ // very wide values get abbreviated
+ $table->cell(truncate_and_popup($tag['value'],$tag_value_threshold));
$table->cell($node_name);
$table->cell($nodegroup_name);
if ($tags_privileges) $table->cell ($form->checkbox_html('slice_tag_ids[]',$tag['slice_tag_id']));
return array("display"=>$tag['tagname'],"value"=>$tag['tag_type_id']);
}
$all_tags= $api->GetTagTypes( array ("category"=>"slice*","-SORT"=>"+tagname"), array("tagname","tag_type_id"));
+ if ($profiling) plc_debug_prof('11 tagtypes',count($all_tags));
$selector_tag=array_map("tag_selector",$all_tags);
function node_selector($node) {
return array("display"=>$node["hostname"],"value"=>$node['node_id']);
}
- $all_nodes = $api->GetNodes( array ("node_id" => $slice['node_ids']), array("hostname","node_id"));
- $selector_node=array_map("node_selector",$all_nodes);
+ $selector_node=array_map("node_selector",$slice_nodes);
function nodegroup_selector($ng) {
return array("display"=>$ng["groupname"],"value"=>$ng['nodegroup_id']);
}
$all_nodegroups = $api->GetNodeGroups( array("groupname"=>"*"), array("groupname","nodegroup_id"));
+ if ($profiling) plc_debug_prof('13 nodegroups',count($all_nodegroups));
$selector_nodegroup=array_map("nodegroup_selector",$all_nodegroups);
$table->cell($form->select_html("tag_type_id",$selector_tag,array('label'=>"Choose Tag")));
$peers->block_end($peer_id);
+if ($profiling) plc_debug_prof_end();
+
// Print footer
include 'plc_footer.php';