Class: Redlics::Query

Inherits:
Object
  • Object
show all
Includes:
Operators
Defined in:
lib/redlics/query.rb,
lib/redlics/query/operation.rb

Overview

Query class

Defined Under Namespace

Classes: Operation

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Operators

#&, #-, #-@, #^, #|

Constructor Details

#initialize(event, time_object, options = {}) ⇒ Redlics::Query

Initialization of a query object

Parameters:

  • event (String)

    event name with eventual Redis namespace separator

  • time_object (Symbol)

    time object predefined in Redlics::TimeFrame.init_with_symbol

  • time_object (Hash)

    time object with keys ‘from` and `to`

  • time_object (Range)

    time object as range

  • time_object (Time)

    time object

  • options (Hash) (defaults to: {})

    configuration options



21
22
23
24
25
26
27
# File 'lib/redlics/query.rb', line 21

def initialize(event, time_object, options = {})
  @event = event.freeze
  @time_object = time_object.freeze
  @options = options
  @namespaces = []
  ObjectSpace.define_finalizer(self, self.class.finalize(namespaces)) if Redlics.config.auto_clean
end

Instance Attribute Details

#namespacesObject (readonly)

Gives read access to the listed instance variables.



10
11
12
# File 'lib/redlics/query.rb', line 10

def namespaces
  @namespaces
end

Class Method Details

.analyze(*args) ⇒ Redlics::Query

Short query access to analyze data.

Parameters:

  • *args (Array)

    list of arguments of the query

Returns:



156
157
158
159
160
161
162
163
164
165
166
# File 'lib/redlics/query.rb', line 156

def analyze(*args)
  options = args.last.instance_of?(Hash) ? args.pop : {}
  query = case args.size
          when 2
            Query.new(args[0], args[1], options)
          when 3
            Query.new(args[0], args[1], options.merge!({ id: args[2].to_i }))
          end
  return yield query if block_given?
  query
end

.finalize(namespaces) ⇒ Integer, NilClass

Finalize query called from garbage collector.

Parameters:

  • namespaces (Array)

    list of created operation keys in Redis

Returns:

  • (Integer)

    result of Redis delete keys

  • (NilClass)

    nil if namespaces are empty



173
174
175
# File 'lib/redlics/query.rb', line 173

def finalize(namespaces)
  proc { reset_redis_namespaces(namespaces) }
end

.reset_redis_namespaces(namespaces) ⇒ Integer, NilClass

Reset Redis created namespace keys.

Parameters:

  • namespaces (Array)

    list of created operation keys in Redis

Returns:

  • (Integer)

    result of Redis delete keys

  • (NilClass)

    nil if namespaces are empty



182
183
184
# File 'lib/redlics/query.rb', line 182

def reset_redis_namespaces(namespaces)
  Redlics.redis { |r| r.del(namespaces) } if namespaces.any?
end

Instance Method Details

#countsInteger

Get or process counts on Redis.

Returns:

  • (Integer)

    count result of given query



31
32
33
34
35
36
37
# File 'lib/redlics/query.rb', line 31

def counts
  @counts ||= (
    result = Redlics.script(Redlics::LUA_SCRIPT, [], ['counts'.to_msgpack, realize_counts!.to_msgpack,
                            { bucketized: Redlics.config.bucket }.to_msgpack])
    result.is_a?(Array) ? result.map(&:to_i).reduce(0, :+) : result.to_i
  )
end

#exists?Boolean, NilClass

Check if object id exists in track bits.

Returns:

  • (Boolean)

    true if exists, false if not

  • (NilClass)

    nil if no object id is given



60
61
62
# File 'lib/redlics/query.rb', line 60

def exists?
  @exists ||= @options[:id] ? Redlics.redis { |r| r.getbit(track_bits, @options[:id]) } == 1 : nil
end

#is_leaf?Boolean

Check if query is a leaf. A query is always a leaf. This method is required for query operations.

Returns:

  • (Boolean)

    true



146
147
148
# File 'lib/redlics/query.rb', line 146

def is_leaf?
  true
end

#plot_countsHash, NilClass

Get or process counts and plot.

Returns:

  • (Hash)

    with date times and counts

  • (NilClass)

    nil if result has errors



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/redlics/query.rb', line 68

def plot_counts
  @plot_counts ||= (
    result = JSON.parse(
      Redlics.script(Redlics::LUA_SCRIPT, [], ['plot_counts'.to_msgpack, realize_counts!.to_msgpack,
                     { bucketized: Redlics.config.bucket }.to_msgpack])
    )
    format_plot(Redlics::CONTEXTS[:counter], result)
  )
rescue JSON::ParserError
  nil
end

#plot_tracksHash, NilClass

Get or process tracks and plot.

Returns:

  • (Hash)

    with date times and counts

  • (NilClass)

    nil if result has errors



84
85
86
87
88
89
90
91
92
93
94
# File 'lib/redlics/query.rb', line 84

def plot_tracks
  @plot_tracks ||= (
    result = JSON.parse(
    Redlics.script(Redlics::LUA_SCRIPT, [], ['plot_tracks'.to_msgpack, realize_tracks!.to_msgpack,
                   {}.to_msgpack])
    )
    format_plot(Redlics::CONTEXTS[:tracker], result)
  )
rescue JSON::ParserError
  nil
end

#realize_counts!Array

Get or process counts and show keys to analyze.

Returns:

  • (Array)

    list of keys to analyze



98
99
100
101
102
103
104
# File 'lib/redlics/query.rb', line 98

def realize_counts!
  @realize_counts ||= (
    keys = Key.timeframed(Redlics::CONTEXTS[:counter], @event, @time_object, @options)
    raise Exception::LuaRangeError if keys.length > 8000
    keys
  )
end

#realize_tracks!Array

Get or process tracks and show keys to analyze.

Returns:

  • (Array)

    list of keys to analyze



108
109
110
111
112
113
114
# File 'lib/redlics/query.rb', line 108

def realize_tracks!
  @realize_tracks ||= (
    keys = Key.timeframed(Redlics::CONTEXTS[:tracker], @event, @time_object, @options)
    raise Exception::LuaRangeError if keys.length > 8000
    keys
  )
end

#reset!(space = nil) ⇒ Boolean

Reset processed data (also operation keys on Redis).

Parameters:

  • space (Symbol) (defaults to: nil)

    define space to reset

  • space (String) (defaults to: nil)

    define space to reset

Returns:

  • (Boolean)

    true



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/redlics/query.rb', line 121

def reset!(space = nil)
  space = space.to_sym if space
  case space
  when :counts, :plot_counts, :plot_tracks, :realize_counts, :realize_tracks
    instance_variable_set("@#{space}", nil)
  when :tracks, :exists
    instance_variable_set("@#{space}", nil)
    reset_track_bits
  when :counter
    @counts, @plot_counts, @realize_counts = [nil] * 3
  when :tracker
    @tracks, @exists, @plot_tracks, @realize_tracks = [nil] * 4
    reset_track_bits
  else
    @counts, @tracks, @exists, @plot_counts, @plot_tracks, @realize_counts, @realize_tracks = [nil] * 7
    reset_track_bits
    self.class.reset_redis_namespaces(@namespaces)
    @namespaces = []
  end
  return true
end

#track_bitsString

Get or process track bits on Redis.

Returns:

  • (String)

    key of track bits result



47
48
49
50
51
52
53
54
55
# File 'lib/redlics/query.rb', line 47

def track_bits
  @track_bits ||= (
    @track_bits_namespace = Key.unique_namespace
    @namespaces << @track_bits_namespace
    Redlics.script(Redlics::LUA_SCRIPT, [], ['operation'.to_msgpack, realize_tracks!.to_msgpack,
                   { operator: 'OR', dest: Key.with_namespace(@track_bits_namespace) }.to_msgpack])
    @track_bits_namespace
  )
end

#tracksInteger

Get or process tracks on Redis.

Returns:

  • (Integer)

    tracks result of given query



41
42
43
# File 'lib/redlics/query.rb', line 41

def tracks
  @tracks ||= Redlics.redis { |r| r.bitcount(track_bits) }
end