Class: NoSE::Index

Inherits:
Object show all
Defined in:
lib/nose/indexes.rb

Overview

A representation of materialized views over fields in an entity

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash_fields, order_fields, extra, graph, saved_key: nil) ⇒ Index

Returns a new instance of Index.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/nose/indexes.rb', line 10

def initialize(hash_fields, order_fields, extra, graph,
               saved_key: nil)
  order_set = order_fields.to_set
  @hash_fields = hash_fields.to_set
  @order_fields = order_fields.delete_if { |e| hash_fields.include? e }
  @extra = extra.to_set.delete_if do |e|
    @hash_fields.include?(e) || order_set.include?(e)
  end
  @all_fields = Set.new(@hash_fields).merge(order_set).merge(@extra)

  validate_hash_fields

  # Store whether this index is an identity
  @identity = @hash_fields == [
    @hash_fields.first.parent.id_field
  ].to_set && graph.nodes.size == 1

  @graph = graph
  @path = graph.longest_path
  @path = nil unless @path.length == graph.size

  validate_graph

  build_hash saved_key
end

Instance Attribute Details

#all_fieldsObject (readonly)

Returns the value of attribute all_fields.



6
7
8
# File 'lib/nose/indexes.rb', line 6

def all_fields
  @all_fields
end

#entriesObject (readonly)

Returns the value of attribute entries.



6
7
8
# File 'lib/nose/indexes.rb', line 6

def entries
  @entries
end

#entry_sizeObject (readonly)

Returns the value of attribute entry_size.



6
7
8
# File 'lib/nose/indexes.rb', line 6

def entry_size
  @entry_size
end

#extraObject (readonly)

Returns the value of attribute extra.



6
7
8
# File 'lib/nose/indexes.rb', line 6

def extra
  @extra
end

#graphObject (readonly)

Returns the value of attribute graph.



6
7
8
# File 'lib/nose/indexes.rb', line 6

def graph
  @graph
end

#hash_countObject (readonly)

Returns the value of attribute hash_count.



6
7
8
# File 'lib/nose/indexes.rb', line 6

def hash_count
  @hash_count
end

#hash_fieldsObject (readonly)

Returns the value of attribute hash_fields.



6
7
8
# File 'lib/nose/indexes.rb', line 6

def hash_fields
  @hash_fields
end

#order_fieldsObject (readonly)

Returns the value of attribute order_fields.



6
7
8
# File 'lib/nose/indexes.rb', line 6

def order_fields
  @order_fields
end

#pathObject (readonly)

Returns the value of attribute path.



6
7
8
# File 'lib/nose/indexes.rb', line 6

def path
  @path
end

#per_hash_countObject (readonly)

Returns the value of attribute per_hash_count.



6
7
8
# File 'lib/nose/indexes.rb', line 6

def per_hash_count
  @per_hash_count
end

#sizeObject (readonly)

Returns the value of attribute size.



6
7
8
# File 'lib/nose/indexes.rb', line 6

def size
  @size
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Two indices are equal if they contain the same fields

Returns:

  • (Boolean)


88
89
90
# File 'lib/nose/indexes.rb', line 88

def ==(other)
  hash == other.hash
end

#[](field_id) ⇒ Fields::Field

Look up a field in the index based on its ID

Returns:



50
51
52
# File 'lib/nose/indexes.rb', line 50

def [](field_id)
  @all_fields.find { |field| field.id == field_id }
end

#contains_field?(field) ⇒ Boolean

Check if the index contains a given field

Returns:

  • (Boolean)


110
111
112
# File 'lib/nose/indexes.rb', line 110

def contains_field?(field)
  @all_fields.include? field
end

#hashObject



104
105
106
# File 'lib/nose/indexes.rb', line 104

def hash
  @hash ||= Zlib.crc32 hash_str
end

#hash_strString

Hash based on the fields, their keys, and the graph

Returns:

  • (String)


95
96
97
98
99
100
101
102
# File 'lib/nose/indexes.rb', line 95

def hash_str
  @hash_str ||= [
    @hash_fields.map(&:id).sort!,
    @order_fields.map(&:id),
    @extra.map(&:id).sort!,
    @graph.unique_edges.map(&:canonical_params).sort!
  ].to_s.freeze
end

#id_graph?Boolean

Check if this index is an ID graph

Returns:

  • (Boolean)


56
57
58
# File 'lib/nose/indexes.rb', line 56

def id_graph?
  @hash_fields.all?(&:primary_key?) && @order_fields.all?(&:primary_key)
end

#identity?Boolean

Check if this index maps from the primary key to fields from one entity

Returns:

  • (Boolean)


38
39
40
# File 'lib/nose/indexes.rb', line 38

def identity?
  @identity
end

#keyString

A simple key which uniquely identifies the index

Returns:

  • (String)


44
45
46
# File 'lib/nose/indexes.rb', line 44

def key
  @key ||= "i#{Zlib.crc32 hash_str}"
end

#to_colorObject

:nocov:



75
76
77
78
79
80
81
82
83
# File 'lib/nose/indexes.rb', line 75

def to_color
  fields = [@hash_fields, @order_fields, @extra].map do |field_group|
    '[' + field_group.map(&:inspect).join(', ') + ']'
  end

  "[magenta]#{key}[/] #{fields[0]} #{fields[1]}#{fields[2]}" \
    " [yellow]$#{size}[/]" \
    " [magenta]#{@graph.inspect}[/]"
end

#to_id_graphObject

Produce an index with the same fields but keyed by entities in the graph



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/nose/indexes.rb', line 61

def to_id_graph
  return self if id_graph?

  all_ids = (@hash_fields.to_a + @order_fields + @extra.to_a)
  all_ids.map! { |f| f.parent.id_field }.uniq!

  hash_fields = [all_ids.first]
  order_fields = all_ids[1..-1]
  extra = @all_fields - hash_fields - order_fields

  Index.new hash_fields, order_fields, extra, @graph
end