class Aio::Module::SpecialStyle::CompareWithDeviceManager

Attributes

device_manager[RW]

用于传递已经分析好的现有的device

input_benchmark[RW]

用于传递由上一次成的device_manager信息

Public Class Methods

new() click to toggle source
Calls superclass method Aio::Module::SpecialStyle::new
# File lib/modules/special/style/compare_with_device_manager.rb, line 16
def initialize
  super({
    :author           => "Elin",
    :description => "此模块用于解析两次生成的device_manager值",
  })
end

Public Instance Methods

clear_other_info(device_warning, input_benchmark) click to toggle source

只留下要比较的两个数据有共同命令的交集,其他的命令就丢弃 因为即使是保留了,产生的也是大量的垃圾信息

# File lib/modules/special/style/compare_with_device_manager.rb, line 54
def clear_other_info(device_warning, input_benchmark)
  device_arr = {}
  input_arr  = {}

  # 获得命令信息
  device_warning.each_pair    { |k, v| device_arr[k] = v.keys }
  input_benchmark.each_pair { |k, v| input_arr[k]  = v.keys }

  # 删除 device_warning 中多余的命令信息
  device_warning.each_pair do |name, hash|
    hash.delete_if do |k, v|
      next true unless input_arr.has_key?(name)
      input_arr[name].include?(k) ? false : true
    end
  end

  # 删除 input_benchmark 中多余的命令信息
  input_benchmark.each_pair do |name, hash|
    hash.delete_if do |k, v|
      next true unless device_arr.has_key?(name)
      device_arr[name].include?(k) ? false : true
    end
  end
end
compare(cm1, cm2, opts={}) click to toggle source
# File lib/modules/special/style/compare_with_device_manager.rb, line 79
def compare(cm1, cm2, opts={})
  # NOTE 待加PASS
  @config_compare = Aio::Config::Warning::Compare

  cm1_arr = []
  cm2_arr = []
  Aio::Base::Toolkit::Hash.flat_cm1(cm1,
                                Aio::Base::Toolkit::Chain.new,
                                cm1_arr)

  Aio::Base::Toolkit::Hash.flat_cm2(cm2,
                                Aio::Base::Toolkit::Chain.new,
                                cm2_arr)

  cp = find_diff_2(cm1_arr, cm2_arr)

  diff = { cm1: [], cm2: []}
  # NOTE 还需要加入config_compare
  # diff = {
  #    cm1: [ [device_name, cmd, key, str], .. ],
  #    cm2: [ [device_name, cmd, key, str], .. ]
  # }
  cp[:cm1].each do |e|
    # 加入cmd
    cmd = e[1]
    diff[:cm1] << [e.first, cmd, e[-2], e.last]
  end

  cp[:cm2].each do |e|
    diff[e.first] ||= {}
    # 加入cmd
    cmd = e[1]
    diff[:cm2] << [e.first, cmd, e[-2], e.last]
  end

  #detect_pass?(diff)

  diff
end
detect_pass?(diff) click to toggle source

检查是否为需要忽略的项

# File lib/modules/special/style/compare_with_device_manager.rb, line 120
def detect_pass?(diff)

  # 当没有就返回false,表示不能跳过
  diff.each_value do |elem|

    # 取key值
    elem.delete_if do |e|
      
      key = e[2]
      if @config_compare.has_key?(key.to_sym)
        @config_compare[key] == 'pass' ? true : false
      end
    end
  end
        
end
find_diff(cm1, cm2) click to toggle source

低效率的双循环结构

# File lib/modules/special/style/compare_with_device_manager.rb, line 140
def find_diff(cm1, cm2)
  res = {}
  cm1_dup = cm1.dup
  cm2_dup = cm2.dup

  # res 为相同的内容
  total = cm1.size
  cm1.each_with_index do |link_1, i|

    cm2.each do |link_2|

      # 如果长度不一致,就下一个
      if link_1.size != link_2.size
        next

      else
        name_1 = long_name(link_1)
        name_2 = long_name(link_2)

        if name_1 == name_2
          cm1_dup.delete link_1
          cm2_dup.delete link_2

          # 找到了相同的就跳出小循环
          break
        end

      end
    end

    # 进度条
    progress_bar(total, i+1, '')
  end

  clear_line

  # 获得不同的内容
  res[:cm1] = cm1_dup
  res[:cm2] = cm2_dup

  res
end
find_diff_2(cm1, cm2) click to toggle source

排序后循环,效率更高

# File lib/modules/special/style/compare_with_device_manager.rb, line 191
def find_diff_2(cm1, cm2)
  cm1.concat(cm2)
  cm1.sort! { |x, y| x.string <=> y.string }

  tmp = []
  bool = false
  cm1.each_with_index do |e, i|
    # 当为真的时候,说明是重复的,就跳过
    if bool
      bool = false
      next
    end

    # 当相等的时候,将bool 设置为true,跳过
    if e.eql? cm1[i+1]
      bool = true
      next
    end

    # 如果和下一个不相等,则说明是单独的,那么就记录
    tmp << e
  end
  
  res = { cm1: [], cm2: [] }
  tmp.each do |e|
    case e.cm_type
    when :cm1
      res[:cm1] << e.line
    when :cm2
      res[:cm2] << e.line
    end
  end

  res
end
long_name(arr) click to toggle source

将一个数组转化成一长串字符作为比较方式

# File lib/modules/special/style/compare_with_device_manager.rb, line 184
def long_name(arr)
  res = ''
  arr.each { |x| res += x.to_s }
  res
end
parse() click to toggle source
# File lib/modules/special/style/compare_with_device_manager.rb, line 23
def parse
  # 将device_manager 中的按照{device_name => useful} 形式重新编排
  # cmds_useful为深度克隆信息,对本体无影响
  device_warning = {}
  input_benchmark_device_warning = {}
  total = device_manager.devices_number
  print_good "总共 #{total} 台设备进行比较"

  device_manager.each_devices_with_index do |device_name, device_klass, i|

    device_warning[device_name] = Aio::Base::Toolkit::DeepClone.clone(device_klass.cmds_useful)
    # 进度条
    progress_bar(total, i+1, device_name)

  end

  input_benchmark.each_devices_with_index do |device_name, device_klass, i|

    input_benchmark_device_warning[device_name] = Aio::Base::Toolkit::DeepClone.clone(device_klass.cmds_useful)
    # 进度条
    progress_bar(total, i+1, device_name)

  end

  clear_line
  clear_other_info(device_warning, input_benchmark_device_warning)
  compare(device_warning, input_benchmark_device_warning)
end