Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Iterating through process hierarchy

by ovedpo15 (Monk)
on Jan 06, 2019 at 15:25 UTC ( #1228107=perlquestion: print w/replies, xml ) Need Help??

ovedpo15 has asked for the wisdom of the Perl Monks concerning the following question:

Hi guys,
I sorry that it will be a long thread and with a lot of data.
Also, I hope I'll make my point (English is my third language).
Before trying to explain my issue, I'll try to explain what I did.
On my previous thread (link:https://www.perlmonks.org/?node_id=1227383) I asked to convert:
15,10,name3 10,#####,name1 12,10,name2 5,12,name4 8,5,name4
to a file with the following format: id,parent-id,name.
With your help (BTW thanks again guys!), I created the following function:
my %data = ( '10517' => { 'parent' => '10516', 'start' => 1545321095, 'end' => 1545321098, 'name' => 'A' }, '10515' => { 'parent' => '10513', 'start' => 1545321091, 'end' => 1545321095, 'name' => 'B' }, '10514' => { 'parent' => '10513', 'start' => 1545321091, 'end' => 1545321095, 'name' => 'C' }, '10516' => { 'parent' => '10513', 'start' => 1545321091, 'end' => 1545321095, 'name' => 'D', }, '10511' => { 'parent' => '#####', 'start' => 1545321090, 'end' => 1545321099, 'name' => 'E' }, '10513' => { 'parent' => '10511', 'start' => 1545321091, 'end' => 1545321097, 'name' => 'F' }, ); foreach my $pid (sort(keys(%data))) { my @parent_list; my $temp_id = $pid; while (exists $data{$temp_id}) { push (@parent_list, $data{$temp_id}{name}); $temp_id = $data{$temp_id}{parent}; } my $line = join("\t|||\t",@parent_list)."\n"; print $line; }
output:
E F ||| E C ||| F ||| E B ||| F ||| E D ||| F ||| E A ||| D ||| F ||| E
It works great! it clear and readable (at least for me), and it does not use any additional modules.
Now I would like to explain my issue.
I have created the following two hashes:
First hash:

$VAR1 = { 'A' => { 'pid' => { '5' => 2 }, 'data' => 4 }, 'B' => { 'pid' => { '8' => 1 '12' => 3 }, 'data' => 3 }, 'C' => { 'pid' => { '9' => 3 }, 'data' => 18 }, 'D' => { 'pid' => { '3' => 3 }, 'data' => 15 }, }

Second hash: (as the one was described in the opening, but I didn't include the other data like start and end, so it will be readable)
$VAR1 = { '8' => { 'parent' => '5', 'name' => 'full_B' }, '9' => { 'parent' => '5', 'name' => 'full_C' }, '5' => { 'parent' => '#####', # No parent 'name' => 'full_A' }, '10' => { 'parent' => '8', 'name' => 'full_D' }, '12' => { 'parent' => '8', 'name' => 'full_D' }, }

I'll try to explain a bit about those hashes. The first hash has files as keys.
Each key contains two fields as values - pid and data.
I don't really care about the data, but I do care about the pid.
The pid hash contains all the pids that touched the current path (the key of the main first hash) during the run.
Each pid points to the duration time (also, not important data for now).
The second hash, contains pids as keys and each pid hash two values: parent-pid and and a name.
From the second hash, I can understand that:
<id>,<parent>,<name> 5,###,full_A 8,5,full_B 9,5,full_C 10,8,full_D
I would like to create a file which contains: for each one of the files in the first hash, I would like to create a the chain to get to the '###' main parent.
For example if file A has process 3, file B has process 5 and file C hash process 7 and also we have the following chain: `###->3->5->7` we will get:
A B,A C,B,A
I just iterated through the files and checked each parent id.
Real example:
First hash:
$VAR1 = { '/perl/5.14.1/strict.pm' => { 'pid' => { '7302' => 1, '7287' => 1 }, 'data' => 6 }, './hello_world.pl' => { 'pid' => { '7287' => 2 }, 'data' => 4 }, './bye_world.pl' => { 'pid' => { '7302' => 2 }, 'data' => 4 }, '/some_text.txt/' => { 'pid' => { '7302' => 1, '7287' => 1 }, 'data' => 2 } };
Second hash:
$VAR1 = { '7299' => { 'parent' => '7287', 'name' => 'echo Hello World ' }, '7305' => { 'parent' => '7302', 'name' => 'echo Bye World ' }, '7302' => { 'parent' => '7287', 'name' => './bye_world.pl' }, '7287' => { 'parent' => '###', 'name' => './hello_world.pl' } };
Expected output:
./hello_world.pl /perl/5.14.1/strict.pm,./hello_world.pl /perl/5.14.1/strict.pm,./bye.pl,./hello_world.pl ./bye_world.pl,./hello_world.pl some_text.txt,./hello_world.pl some_text.txt,./bye_world.pl,./hello_world.pl

The second hash has the hierarchy which the first hash should follow.
My main goal is to create a function which creates the file with the data.
The reason I included all the information and the code in the beginning of the thread
is because the issue is similar and I would like to create an efficient function which creates those files (the one from previous thread and the new one).

In summary:
1. I'm trying to create a function which gets two hashes and creates a file which has the following format:
<file1>,<chain-file(N-1)>,<chain-file(N-1)>,...,<chain-file1><br>
2. Combine the function with already existing function.
The reason I like that solution in the previous thread is because its clear, readable and does not include any additional modules.
If you need some additional explanation, I would be more than happy to do so.
Thank you all for the help! Iterating through process hierarchy

Replies are listed 'Best First'.
Re: Iterating through process hierarchy
by tybalt89 (Parson) on Jan 06, 2019 at 19:09 UTC
    #!/usr/bin/perl # https://perlmonks.org/?node_id=1228107 use strict; use warnings; my $firsthash = { "./bye_world.pl" => { data => 4, pid => { 7302 => 2 } }, "./hello_world.pl" => { data => 4, pid => { 7287 => 2 } }, "/perl/5.14.1/strict.pm" => { data => 6, pid => { 7287 => 1, 7302 => + 1 } }, "/some_text.txt/" => { data => 2, pid => { 7287 => 1, 7302 => + 1 } }, }; my $secondhash = { 7287 => { name => "./hello_world.pl", parent => "###" }, 7299 => { name => "echo Hello World ", parent => 7287 }, 7302 => { name => "./bye_world.pl", parent => 7287 }, 7305 => { name => "echo Bye World ", parent => 7302 }, }; sub parents { my ($name, $pid) = @_; exists $secondhash->{$pid} or return ''; my $secondname = $secondhash->{$pid}{name}; return ($name ne $secondname and ",$secondname") . parents($secondname, $secondhash->{$pid}{parent}); } for my $name ( keys %$firsthash ) { for my $pid ( keys %{ $firsthash->{$name}{pid} } ) { print $name, parents($name, $pid), "\n"; } }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1228107]
Approved by johngg
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (2)
As of 2020-06-05 07:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you really want to know if there is extraterrestrial life?



    Results (35 votes). Check out past polls.

    Notices?