1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
package MaxMind::DB::Writer::Tree::Processor::VisualizeTree;
use strict;
use warnings;
use namespace::autoclean;
our $VERSION = '0.300003';
use Data::Dumper::Concise;
use Digest::MD5 qw( md5_hex );
use GraphViz2;
use Net::Works::Network;
use Moose;
has ip_version => (
is => 'ro',
isa => 'Int',
required => 1,
);
has show_full_data_record => (
is => 'ro',
isa => 'Bool',
default => 0,
);
has graph => (
is => 'ro',
isa => 'GraphViz2',
init_arg => undef,
default => sub { GraphViz2->new( global => { directed => 1 } ) },
);
has _labels => (
is => 'ro',
init_arg => undef,
default => sub { {} },
);
## no critic (Subroutines::ProhibitManyArgs)
sub process_node_record {
my $self = shift;
my $node_num = shift;
my $dir = shift;
my $node_ip_num = shift;
my $node_prefix_length = shift;
my $record_ip_num = shift;
my $record_prefix_length = shift;
my $record_node_num = shift;
$self->graph()->add_edge(
from => $self->_label_for_node(
$node_num, $node_ip_num, $node_prefix_length
),
to => $self->_label_for_node(
$record_node_num, $record_ip_num, $record_prefix_length
),
label => ( $dir ? 'RIGHT' : 'LEFT' ),
);
return 1;
}
sub process_empty_record {
return;
}
sub process_data_record {
my $self = shift;
my $node_num = shift;
my $dir = shift;
my $node_ip_num = shift;
my $node_prefix_length = shift;
my $record_ip_num = shift;
my $record_prefix_length = shift;
my $value = shift;
$self->graph()->add_edge(
from => $self->_label_for_node(
$node_num, $node_ip_num, $node_prefix_length
),
to => $self->_network( $record_ip_num, $record_prefix_length ) . ' = '
. $self->_data_record_representation($value),
label => ( $dir ? 'RIGHT' : 'LEFT' ),
);
return 1;
}
sub _label_for_node {
my $self = shift;
my $node_num = shift;
my $ip_num = shift;
my $prefix_length = shift;
my $network = $self->_network( $ip_num, $prefix_length );
return $self->_labels()->{$node_num} //= sprintf(
'Node %d - %s (%s - %s)',
$node_num,
$network->as_string,
$network->first()->as_string,
$network->last()->as_string,
);
}
sub _data_record_representation {
my $self = shift;
my $value = shift;
if ( $self->show_full_data_record() ) {
return quotemeta( Dumper($value) );
}
else {
return md5_hex( Dumper($value) );
}
}
sub _network {
my $self = shift;
my $ip_num = shift;
my $prefix_length = shift;
return Net::Works::Network->new_from_integer(
integer => $ip_num,
prefix_length => $prefix_length,
version => $self->ip_version(),
);
}
__PACKAGE__->meta()->make_immutable();
1;
|