Add logarea param via referer. add bytesToSize. Polish formatting of tooltip
[p5sagit/Devel-Size.git] / static / MemView.pl
CommitLineData
b2fc39a5 1#!/usr/bin/env perl
2
3use strict;
4use warnings;
5
f60f09e5 6use JSON::XS;
b2fc39a5 7use Mojolicious::Lite;
e8f4c506 8use Getopt::Long;
945e07d7 9use Storable qw(dclone);
ee6e37bf 10use Devel::Dwarn;
e8f4c506 11
12GetOptions(
945e07d7 13 'db=s' => \(my $opt_db = '../memnodes.db'),
14 'debug!' => \my $opt_debug,
e8f4c506 15) or exit 1;
b2fc39a5 16
945e07d7 17#warn "Reading from $opt_db\n";
18
b2fc39a5 19use ORLite {
945e07d7 20 file => '../memnodes.db',
b2fc39a5 21 package => "MemView",
22 #user_version => 1,
23 readonly => 1,
24 #unicode => 1,
25};
26
f60f09e5 27my $j = JSON::XS->new;
28
b2fc39a5 29# Documentation browser under "/perldoc"
30plugin 'PODRenderer';
31
32get '/' => sub {
33 my $self = shift;
34 $self->render('index');
35};
36
37get '/jit_tree/:id/:depth' => sub {
38 my $self = shift;
e8f4c506 39
b2fc39a5 40 my $id = $self->stash('id');
41 my $depth = $self->stash('depth');
ee6e37bf 42
43 my $logarea = (defined $self->param('logarea'))
44 ? $self->param('logarea')
45 : Mojo::URL->new($self->req->headers->referrer)->query->param('logarea');
46
875c1073 47 my $node_tree = _fetch_node_tree($id, $depth);
48 my $jit_tree = _transform_node_tree($node_tree, sub {
49 my ($node) = @_;
50 my $children = delete $node->{children}; # XXX edits the src tree
e8f4c506 51 my $area = $node->{self_size}+$node->{kids_size};
945e07d7 52 $node->{'$area'} = ($logarea) ? log($area) : $area; # XXX move to jit js
bb66f8a1 53 my $jit_node = {
54 id => $node->{id},
e8f4c506 55 name => $node->{title} || $node->{name},
bb66f8a1 56 data => $node,
57 };
58 $jit_node->{children} = $children if $children;
59 return $jit_node;
b2fc39a5 60 });
ee6e37bf 61
62 if(1){
63 use Devel::Dwarn;
64 use Data::Dump qw(pp);
65 local $jit_tree->{children};
66 pp(dclone($jit_tree)); # dclone to avoid stringification
67 }
68
b2fc39a5 69 $self->render_json($jit_tree);
70};
71
875c1073 72sub _fetch_node_tree {
73 my ($id, $depth) = @_;
74 my $node = MemView->selectrow_hashref("select * from node where id = ?", undef, $id)
75 or die "Node '$id' not found";
945e07d7 76 $node->{$_} += 0 for (qw(child_count kids_node_count kids_size self_size));
e78b28ca 77 $node->{leaves} = $j->decode(delete $node->{leaves_json});
e8f4c506 78 $node->{attr} = $j->decode(delete $node->{attr_json});
47a0d085 79 $node->{name} .= "->" if $node->{type} == 2 && $node->{name};
e78b28ca 80
5a78486c 81 if ($node->{child_ids}) {
82 my @child_ids = split /,/, $node->{child_ids};
875c1073 83 my $children;
ee6e37bf 84 if (@child_ids == 1
85 && $node->{type} == 2 # only collapse links
86 ) {
5a78486c 87 my $child = _fetch_node_tree($child_ids[0], $depth); # same depth
f9d8678b 88 # merge node into child
5a78486c 89 # XXX id, depth, parent_id
945e07d7 90 warn "Merged $node->{name} #$node->{id} with only child $child->{name} #$child->{id}\n"
91 if $opt_debug;
e74c1998 92 $child->{name} = "$node->{name} $child->{name}";
f9d8678b 93 $child->{$_} += $node->{$_} for (qw(self_size));
5a78486c 94 $child->{$_} = $node->{$_} for (qw(parent_id));
e8f4c506 95
e74c1998 96 $child->{title} = join " ", grep { defined && length } $child->{title}, $node->{title};
945e07d7 97 #warn "Titled $child->{title}" if $child->{title};
e8f4c506 98
99 for my $attr_type (keys %{ $node->{attr} }) {
100 my $src = $node->{attr}{$attr_type};
101 if (ref $src eq 'HASH') { # eg NPattr_NAME: {attr}{1}{$name} = $value
102 my $dst = $child->{attr}{$attr_type} ||= {};
103 for my $k (keys %$src) {
104 warn "Node $child->{id} attr $attr_type:$k=$dst->{$k} overwritten by $src->{$k}\n"
105 if defined $dst->{$k};
106 $dst->{$k} = $src->{$k};
107 }
108 }
47a0d085 109 elsif (ref $src eq 'ARRAY') { # eg NPattr_PADNAME: {attr}{2}[$val] = $name
e8f4c506 110 my $dst = $child->{attr}{$attr_type} ||= [];
111 my $idx = @$src;
112 while (--$idx >= 0) {
113 warn "Node $child->{id} attr $attr_type:$idx=$dst->[$idx] overwritten by $src->[$idx]\n"
114 if defined $dst->[$idx];
115 $dst->[$idx] = $src->[$idx];
116 }
117 }
47a0d085 118 else { # assume scalar
119 warn "Node $child->{id} attr $attr_type=$child->{attr}{$attr_type} overwritten by $src\n"
120 if exists $child->{attr}{$attr_type};
121 $child->{attr}{$attr_type} = $src;
122 }
e8f4c506 123 }
124
e78b28ca 125 $child->{leaves}{$_} += $node->{leaves}{$_}
126 for keys %{ $node->{leaves} };
5a78486c 127
128 $child->{_ids_merged} .= ",$node->{id}";
129 my @child_ids = split /,/, $node->{child_ids};
130 $child->{child_count} = @child_ids;
131
f9d8678b 132 $node = $child;
875c1073 133 }
f9d8678b 134 elsif ($depth) {
5a78486c 135 $children = [ map { _fetch_node_tree($_, $depth-1) } @child_ids ];
f9d8678b 136 $node->{children} = $children;
137 $node->{child_count} = @$children;
875c1073 138 }
b2fc39a5 139 }
b2fc39a5 140 return $node;
141}
142
f9d8678b 143sub _transform_node_tree { # recurse depth first
875c1073 144 my ($node, $transform) = @_;
145 if (my $children = $node->{children}) {
146 $_ = _transform_node_tree($_, $transform) for @$children;
147 }
148 return $transform->($node);
149}
150
b2fc39a5 151
152app->start;
153__DATA__
154@@ index.html.ep
155% layout 'default';
156% title 'Welcome';
157Welcome to the Mojolicious real-time web framework!
158
159@@ layouts/default.html.ep
160<!DOCTYPE html>
161<head>
162<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
bb66f8a1 163<title>Perl Memory Treemap</title>
b2fc39a5 164
165<!-- CSS Files -->
166<link type="text/css" href="css/base.css" rel="stylesheet" />
167<link type="text/css" href="css/Treemap.css" rel="stylesheet" />
168
169<!--[if IE]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->
170
171<!-- JIT Library File -->
172<script language="javascript" type="text/javascript" src="jit.js"></script>
2a627489 173<script language="javascript" type="text/javascript" src="jquery-1.8.1-min.js"></script>
b2fc39a5 174
175<!-- Example File -->
bb66f8a1 176<script language="javascript" type="text/javascript" src="sprintf.js"></script>
b2fc39a5 177<script language="javascript" type="text/javascript" src="tm.js"></script>
178</head>
179
180<body onload="init();">
181<div id="container">
182
183<div id="left-container">
184
b2fc39a5 185<div class="text">
186<h4>
bb66f8a1 187Perl Memory TreeMap
b2fc39a5 188</h4>
47a0d085 189 Click on a node to zoom in.<br /><br />
b2fc39a5 190</div>
191
192<a id="back" href="#" class="theme button white">Go to Parent</a>
e8f4c506 193
194<br />
195<form name=params>
196<label for="logarea">&nbsp;Logarithmic scale
197<input type=checkbox id="logarea" name="logarea">
198</form>
199
b2fc39a5 200</div>
201
202<div id="center-container">
203 <div id="infovis"></div>
204</div>
205
206<div id="right-container">
207
208<div id="inner-details"></div>
209
210</div>
211
212<div id="log"></div>
213</div>
214</body>
215</html>