Реорганизовать хэш в определенном формате - PullRequest
0 голосов
/ 14 января 2019
%files_data = {                                                                                                                                                                                                                                     

              './GetOpt.pm' => {
                          'pid' => {
                                     '56061' => 1,
                                     '56065' => 1
                                   }
                            },
              'file1' => {
                          'pid' => {
                                     '56061' => 2
                                   }
                        },
              'file2' => {
                         'pid' => {
                                    '56065' => 2
                                  }
                       },
              './src/bin/perl' => {
                            'pid' => {
                                       '56061' => 1,
                                       '56065' => 1
                                     }
                          }
                    };

%process_data = (

          '56061' => {
                       'parent' => 'NA',
                       'name' => 'file1'
                     },
          '56069' => {
                       'parent' => '56065',
                       'name' => 'echo Hello_file1'
                     },
          '56062' => {
                       'parent' => '56061',
                       'name' => 'echo Hello_file2'
                     },
          '56065' => {
                       'parent' => '56061',
                       'name' => 'file2'
                     }
        );

Я бы хотел перебрать хеш $files_data и для каждого файла получить цепочку файлов. Поэтому я получу следующий хеш:

%hash = (
        'file1' => {
            '/src/bin/perl' => 1,
            'file2' => { 
                '/src/bin/perl' => 1,
                './GetOpt.pm' => 1
            },
            './GetOpt.pm' => 1,
    }
);

Мне нужно пройти цепочку pid до основного родителя ('NA') для каждого файла.

Каким будет самый эффективный способ ее решения? Мне нужно несколько советов о том, как это сделать.

РЕДАКТИРОВАТЬ : Возьмем, к примеру, './GetOpt.pm' файл. у него есть pid 56061, поэтому мы идем к %process_data и видим 'file1' (который является файлом). Также мы видим, что родительский элемент 56061 равен NA, поэтому мы останавливаемся и получаем:

file1 => ./GetOpt.pm

Но у ./GetOpt.pm есть другой pid - 56065, поэтому мы переходим к 56065 и видим file2 (который является файлом). Затем мы переходим к 56061, который имеет file1 (это файл s). итак получаем:

file1 => file2 => ./GetOpt.pm

Объедините это:

file1 => {
    ./GetOpt.pm,
    file2 => ./GetOpt.pm
}

Я хотел бы построить цепочку файлов процесса (только с файлами). %files_data содержит действительные файлы, а %process_data содержит иерархию процесса, которому мы должны следовать

1 Ответ

0 голосов
/ 14 января 2019

Я использовал рекурсивную подпрограмму, которая добавляет цепочку имен файлов в существующий хеш. Мне пришлось исправить ожидаемую структуру, добавив . к /src/bin/perl.

#!/usr/bin/perl
use warnings;
use strict;

my %files_data = (
    './GetOpt.pm'    => {pid => {56061 => 1,
                                 56065 => 1}},
    'file1'          => {pid => {56061 => 2}},
    'file2'          => {pid => {56065 => 2}},
    './src/bin/perl' => {pid => {56061 => 1,
                                 56065 => 1}}
);

my %process_data = (
    '56061' => {'parent' => 'NA',
                'name' => 'file1'},
    '56069' => {'parent' => '56065',
                'name' => 'echo Hello_file1'},
    '56062' => {'parent' => '56061',
                'name' => 'echo Hello_file2'},
    '56065' => {'parent' => '56061',
                'name' => 'file2'}
);

my %expected = (
    'file1' => {
        './src/bin/perl' => 1,
        'file2' => {
            './src/bin/perl' => 1,
            './GetOpt.pm' => 1
        },
        './GetOpt.pm' => 1,
    }
);

use Test::More;
use Test::Deep;

sub hashify {
    my ($tree, @chain) = @_;
    my $head = shift @chain;
    $tree->{$head} = @chain ? {} : 1 unless ref $tree->{$head};
    hashify($tree->{$head}, @chain) if @chain;
}

sub add {
    my ($tree, $key) = @_;
    for my $pid (keys %{ $files_data{$key}{pid} }) {
        my @chain = $key;
        while ($pid ne 'NA') {
            my ($parent, $name) = @{ $process_data{$pid} }{qw{ parent name }};
            unshift @chain, $name unless $name eq $chain[0];
            $pid = $parent;
        }
        hashify($tree, @chain);
    }
}

my $result = {};
add($result, $_) for keys %files_data;

cmp_deeply($result, \%expected);
done_testing();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...