Ruby diff два хеша и объединить в цикле с накопленной суммой - PullRequest
0 голосов
/ 17 сентября 2018

нужна помощь с рубином!

У меня есть цикл с я собираю данные о процессах PHP (PID, Utimes). У меня есть два хэша. Первый 'h1' выглядит так:

"domain1" => { :utime => 0, :last_seen => 0, :process_count => 0, :process_count_avg => 0 },
"domain2" => { :utime => 0, :last_seen => 0, :process_count => 0, :process_count_avg => 0 }

Это код для этого:

h1[vhostname] ||= { :utime => 0, :last_seen => 0, :process_count => 0, :process_count_avg => 0 }
h1[vhostname][:utime] += utime_proc 
h1[vhostname][:last_seen] = 0

'vhostname' - строка, содержащая доменное имя. 'utime_proc' является значением utime.

В каждом цикле я суммирую все времена для всех процессов конкретной области, а на выходе - Домен и его суммированное время. Но это искажает реальное состояние.

Что мне нужно сделать, так это сделать кумулятивную сумму времени для определенного домена. Чтобы быть суммой времени для всех текущих процессов, но добавить сумму времени для всех процессов, которые уже закончились. Мне, вероятно, придется хранить процессы pid для каждого дочернего домена utime, и если этот процесс исчезнет, ​​его последнее время добавляется к значению по умолчанию (хэш 'h1'): utime в этом домене.

Итак, я создаю еще два хэша: 'h2' и 'h3'. Значение 'h3' сбрасывается в каждом цикле цикла, и в нем хранятся все PID для (под) домена с его временами следующим образом:

h3[vhostname] = []
h3[vhostname] << {:pid => pid, :utime => utime_proc}

хеш 'h2' хранит PID из всех циклов цикла раньше, так же, как и 'h3', но не сбрасывает:

if not h2.key?(vhostname)
h2[vhostname] = []
h2[vhostname] << {:pid => pid, :utime => utime_proc}
end

Выходной хеш должен выглядеть следующим образом:

{"domain1"=>[{:pid=>2, :utime=>20}, {:pid=>1, :utime=>10}], "domain2"=>[{:pid=>1, :utime=>10}, {:pid=>3, :utime=>30}]}

Теперь мне нужно помочь с: 1. вероятно, разнесите эти два хэша, и, если PID для dispapear, мне нужно удалить их из хэша 'h2' и суммы его последнего значения utime в значение utime, хранящееся в 'h1'. 2. Если для домена появляется новый PID (в 'h3' - новый pid, а в 'h2' - нет), добавьте этот PID в 'h2', указав его utime для определенного домена.

И это то, что я не могу сделать. Я знаю, что могу просто сделать:

'h2-h3' или 'h3-h2', но я не знаю, что делать с результатом и как с ним справиться.

Ребята, вы можете мне помочь, пожалуйста? Краткая версия моего кода ниже. Я все еще рубиновый новичок.

h1 = {}
# Hash to collect PID and its utimes
h2 = {}

loop do  

# Hash to temporarly store PID and its utimes - in each cycle is reseting
h3 = {}

# Here I collect processes
#############
#############

# Collect PIDs and its utimes
# Store PIDs and its utimes temporarly - only for this loop round
h3[vhostname] = []
h3[vhostname] << {:pid => pid, :utime => utime_proc}

# is h2 empty? if so, this is probably first loop round
if not h2.key?(vhostname)
h2[vhostname] = []
h2[vhostname] << {:pid => pid, :utime => utime_proc}
else
# h2 is not empty, we can diff and sum
# PROBABLY PLACE I NEED TO HELP WITH

end
# Here I do some more magic with h1 and output the result with some delay
end

UPDATE

Я изменил структуру хеширования h2 и h3 на:

{:domain => "domain1.com", :pid => XXXX, :utime => YYYYY}

1 Ответ

0 голосов
/ 17 сентября 2018

Я не буду пытаться реализовать вашу логику, но я попытаюсь объяснить, что касается хэшей. Ради простоты я не зацикливался, а имел дело с тестовыми данными

domains = ['domain1','domain2','domain3']

h1 = {}
h2 = {}
# generate blank template for each domain
domains.each { |vhostname|
  h1[vhostname] ||= { :utime => 0, :last_seen => 0, :process_count => 0, :process_count_avg => 0 }
  h2[vhostname] ||= {}
}

# dummy loop
1.upto(5) {
  h3={}
  # start collecting data for each domain
  domains.each { |vhostname|
    # TEST DATA
    h3[vhostname] ||= {}
    1.upto(5) {
      _pid = rand(1..10)
      h3[vhostname][:"#{_pid}"] ||= {:utime => rand(9999)}
    }
    # TEST DATA

    h2[vhostname].merge!(h3[vhostname])
    h2[vhostname].each { |proc, details|
      unless h3[vhostname].key?(proc)
        h1[vhostname][:utime] = h1[vhostname][:utime] + details[:utime]
      end
    }
    h2[vhostname] = h2[vhostname].keep_if { |proc| h3[vhostname].key?(proc)}
  }
}
...