class CSVDecision::Index
Build an index for a decision table with one or more input columns designated as keys @api private
Attributes
@return [Array<Integer>] Array of column indices
@return [Hash] The index hash mapping in input values to one or more data array row indexes.
Public Class Methods
Build the index on the designated number of input columns.
@param table [CSVDecision::Table] Decision
table being indexed. @return [CSVDecision::Index] The built index.
# File lib/csv_decision/index.rb, line 16 def self.build(table:) # Do we even have an index? key_cols = index_columns(columns: table.columns.ins) return if key_cols.empty? table.index = Index.new(table: table, columns: key_cols) # Indexed columns do not need to be scanned trim_scan_rows(scan_rows: table.scan_rows, index_columns: table.index.columns) table end
@param table [CSVDecision::Table] Decision
table. @param columns [Array<Index>] Array of column indexes to be indexed.
# File lib/csv_decision/index.rb, line 79 def initialize(table:, columns:) @columns = columns @hash = {} build(table) freeze end
@param current_value [Integer, Array] Current index key value. @param index [Integer] Array row index to be included in the table index entry. @return [Integer, Array] New index key value.
# File lib/csv_decision/index.rb, line 32 def self.value(current_value, index) return integer_value(current_value, index) if current_value.is_a?(Integer) array_value(current_value, index) current_value end
Private Class Methods
Current value is an array of row indexes
# File lib/csv_decision/index.rb, line 61 def self.array_value(current_value, index) start_row, end_row = current_value.last end_row = start_row if end_row.nil? # Is the new row index contiguous with the last start row/end row range? end_row + 1 == index ? current_value[-1] = [start_row, index] : current_value << index end
# File lib/csv_decision/index.rb, line 45 def self.index_columns(columns:) key_cols = [] columns.each_pair { |col, column| key_cols << col if column.indexed } key_cols end
Current value is a row index integer
# File lib/csv_decision/index.rb, line 54 def self.integer_value(current_value, index) # Is the new row index contiguous with the last start row/end row range? current_value + 1 == index ? [[current_value, index]] : [current_value, index] end
# File lib/csv_decision/index.rb, line 40 def self.trim_scan_rows(scan_rows:, index_columns:) scan_rows.each { |scan_row| scan_row.constants = scan_row.constants - index_columns } end
Private Instance Methods
# File lib/csv_decision/index.rb, line 90 def build(table) table.each do |row, index| key = build_key(row: row) current_value = @hash.key?(key) @hash[key] = current_value ? Index.value(@hash[key], index) : index end end
# File lib/csv_decision/index.rb, line 99 def build_key(row:) if @columns.count == 1 row[@columns[0]] else @columns.map { |col| row[col] } end end