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