Ruby 区分两个哈希并在循环中合并累积总和

Ruby diff two hashes and merge in loop with cumulative sum

需要 ruby 帮助!

我在循环中收集有关 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 值。

在每个循环中,我对特定域的所有进程的所有 utime 求和,输出是 Domain 及其总和 utime。但这扭曲了真实状态。

我需要做的是对特定域的 utimes 进行累计。为所有当前进程的 utime 总和,但加上所有已结束进程的 utime 总和。我可能必须为每个子域 utime 存储 pid 进程,如果这个进程消失,它的最后一个 utime 被添加到默认值('h1' 哈希):那个域的 utime。

因此,我创建了另外两个散列:'h2' 和 'h3'。 'h3' 的值在每个循环中都会重置,这会存储(子)域的所有 PID 及其 utimes,如下所示:

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 消失,我需要将它们从 'h2' 散列中删除,并且它的最后一个 utime 值总和存储在 'h1' 中的 utime 值。 2. 我为域出现了新的 PID(在 'h3' 中是新的 pid,在 'h2' 中还没有),将此 PID 添加到 'h2',并将其 utime 添加到特定域。

这些是我做不到的。我知道我可以简单地做:

'h2-h3' 或 'h3-h2' 但我不知道如何处理结果以及如何处理它。

伙计们,你能帮帮我吗?我的代码的简短版本如下。我还是 ruby-新手。

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

更新

我将 h2 和 h3 哈希结构更改为:

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

我不会尝试实现您的逻辑,但处理哈希是我将尝试阐明的内容。为了简单起见,我没有循环,只是处理了测试数据

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)}
  }
}