on-demand treemap working, though rough
[p5sagit/Devel-Size.git] / memnodes.pl
CommitLineData
2c631ee0 1#!/bin/env perl
2
3use strict;
4use warnings;
5
b2fc39a5 6use DBI;
7use DBD::SQLite;
8
fc6614ee 9use Getopt::Long;
10
11GetOptions(
12 'json!' => \my $opt_json,
b2fc39a5 13 'db=s' => \my $opt_db,
fc6614ee 14) or exit 1;
94fab3d1 15
b2fc39a5 16my $dbh = DBI->connect("dbi:SQLite:dbname=$opt_db","","", {
17 RaiseError => 1, PrintError => 0, AutoCommit => 0
18});
19$dbh->do("PRAGMA synchronous = OFF");
20$dbh->do("DROP TABLE IF EXISTS node");
21$dbh->do(q{
22 CREATE TABLE node (
23 id integer primary key,
24 name text,
25 depth integer,
26 parent_seqn integer,
27
28 self_size integer,
29 kids_size integer,
30 kids_node_count integer,
31 child_seqns text
32 )
33});
34my $node_ins_sth = $dbh->prepare(q{
35 INSERT INTO node VALUES (?,?,?,?, ?,?,?,?)
36});
37
2c631ee0 38my @stack;
39my %seqn2node;
40
94fab3d1 41sub enter_node {
42 my $x = shift;
43 if ($opt_json) {
44 print " " x $x->{depth};
b2fc39a5 45 print qq({ "id": "$x->{id}", "name": "$x->{name}", "depth":$x->{depth}, "children":[ \n);
94fab3d1 46 }
47 return;
48}
49
50sub leave_node {
51 my $x = shift;
b2fc39a5 52 delete $seqn2node{$x->{id}};
94fab3d1 53 my $self_size = 0; $self_size += $_ for values %{$x->{leaves}};
54 $x->{self_size} = $self_size;
2c631ee0 55 if (my $parent = $stack[-1]) {
56 # link to parent
b2fc39a5 57 $x->{parent_seqn} = $parent->{id};
2c631ee0 58 # accumulate into parent
59 $parent->{kids_node_count} += 1 + ($x->{kids_node_count}||0);
94fab3d1 60 $parent->{kids_size} += $self_size + $x->{kids_size};
b2fc39a5 61 push @{$parent->{child_seqn}}, $x->{id};
2c631ee0 62 }
63 # output
64 # ...
94fab3d1 65 if ($opt_json) {
66 print " " x $x->{depth};
67 my $size = $self_size + $x->{kids_size};
68 print qq(], "data":{ "\$area": $size } },\n);
69 }
b2fc39a5 70 if ($dbh) {
71 $node_ins_sth->execute(
72 $x->{id}, $x->{name}, $x->{depth}, $x->{parent_seqn},
73 $x->{self_size}, $x->{kids_size}, $x->{kids_node_count},
74 $x->{child_seqn} ? join(",", @{$x->{child_seqn}}) : undef
75 );
76 # XXX attribs
77 }
94fab3d1 78 return;
2c631ee0 79}
80
94fab3d1 81print "memnodes = [" if $opt_json;
82
2c631ee0 83while (<>) {
84 chomp;
b2fc39a5 85 my ($type, $id, $val, $name, $extra) = split / /, $_, 5;
2c631ee0 86 if ($type eq "N") { # Node ($val is depth)
87 while ($val < @stack) {
94fab3d1 88 leave_node(my $x = pop @stack);
b2fc39a5 89 warn "N $id d$val ends $x->{id} d$x->{depth}: size $x->{self_size}+$x->{kids_size}\n";
2c631ee0 90 }
91 die 1 if $stack[$val];
b2fc39a5 92 my $node = $stack[$val] = { id => $id, name => $name, extra => $extra, attr => [], leaves => {}, depth => $val, self_size=>0, kids_size=>0 };
94fab3d1 93 enter_node($node);
b2fc39a5 94 $seqn2node{$id} = $node;
2c631ee0 95 }
96 elsif ($type eq "L") { # Leaf name and memory size
b2fc39a5 97 my $node = $seqn2node{$id} || die;
2c631ee0 98 $node->{leaves}{$name} += $val;
99 }
100 elsif ($type eq "A") { # Attribute name and value
b2fc39a5 101 my $node = $seqn2node{$id} || die;
2c631ee0 102 push @{ $node->{attr} }, $name, $val; # pairs
103 }
104 else {
105 warn "Invalid type '$type' on line $. ($_)";
106 }
b2fc39a5 107 $dbh->commit if $dbh and $id % 10_000 == 0;
2c631ee0 108}
109
110my $x;
111while (@stack > 1) {
94fab3d1 112 leave_node($x = pop @stack) while @stack;
b2fc39a5 113 warn "EOF ends $x->{id} d$x->{depth}: size $x->{self_size}+$x->{kids_size}\n";
2c631ee0 114}
94fab3d1 115print " ];\n" if $opt_json;
116
b2fc39a5 117$dbh->commit if $dbh;
118
2c631ee0 119use Data::Dumper;
120warn Dumper(\$x);
121warn Dumper(\%seqn2node);
122
123=for
124SV(PVAV) fill=1/1 [#1 @0]
125: +64 sv =64
126: +16 av_max =80
127: AVelem-> [#2 @1]
128: : SV(RV) [#3 @2]
129: : : +24 sv =104
130: : : RV-> [#4 @3]
131: : : : SV(PVAV) fill=-1/-1 [#5 @4]
132: : : : : +64 sv =168
133: AVelem-> [#6 @1]
134: : SV(IV) [#7 @2]
135: : : +24 sv =192
136192 at -e line 1.
137=cut
138__DATA__
139N 1 0 SV(PVAV) fill=1/1
140L 1 64 sv
141L 1 16 av_max
142N 2 1 AVelem->
143N 3 2 SV(RV)
144L 3 24 sv
145N 4 3 RV->
146N 5 4 SV(PVAV) fill=-1/-1
147L 5 64 sv
148N 6 1 AVelem->
149N 7 2 SV(IV)
150L 7 24 sv