Class: Australium::EventCache

Inherits:
Object
  • Object
show all
Includes:
EventFilters
Defined in:
lib/australium/cache/event_cache.rb

Overview

Allows access to events in an Australium database. Unlike a direct Mongo connection, the EventCache will return a fully-formed Event object.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from EventFilters

#chat_messages, #connects, #disconnects, #entrances, #kills, #map_loads, #map_starts, #name_changes, #role_changes, #suicides, #team_joins, #triggers

Constructor Details

#initialize(db) ⇒ EventCache

Creates a new instance of EventCache.

Parameters:

  • db (Mongo::Database)

20
21
22
# File 'lib/australium/cache/event_cache.rb', line 20

def initialize(db)
  @db = db
end

Instance Attribute Details

#dbObject

Returns the value of attribute db


16
17
18
# File 'lib/australium/cache/event_cache.rb', line 16

def db
  @db
end

Instance Method Details

#has_game?(game_hash) ⇒ TrueClass

Returns true if this game's data has been cached.

Parameters:

  • game_hash (Fixnum)

    hash of a game_log

Returns:

  • (TrueClass)

    whether or not the data from this game_log has been cached


27
28
29
30
31
32
33
# File 'lib/australium/cache/event_cache.rb', line 27

def has_game?(game_hash)
  begin
    @db["MapLoad"].find(:game_id => game_hash).to_a.count > 0 && @db["GameEnd"].find(:game_id => game_hash).to_a.count > 0
  rescue
    false
  end
end

#hash_to_obj(hash) ⇒ Object

FIXME: This could be more clever.


51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/australium/cache/event_cache.rb', line 51

def hash_to_obj(hash)
  hash.each_pair do |key, value|
    hash[key] = hash_to_obj(value) if value.is_a?(Hash)
    hash[key] = value.map { |x| hash_to_obj(x) if x.is_a?(Hash) } if value.is_a?(Array)
  end

  begin
    obj_class = Australium.const_get(hash[:class])
  rescue
    obj_class = OpenStruct
  end

  obj_class.new(hash)
end

#obj_to_hash(obj) ⇒ Object

FIXME: This could be more clever, and probably combined with hash_to_obj.


67
68
69
70
71
72
73
74
75
76
# File 'lib/australium/cache/event_cache.rb', line 67

def obj_to_hash(obj)
  obj.each_pair do |key, value|
    obj[key] = obj_to_hash(value) if value.is_a?(OpenStruct)
    obj[key] = value.map { |x| obj_to_hash(x) if x.is_a?(OpenStruct) } if value.is_a?(Array)
  end

  obj[:class] = obj.class.to_s.split('::').last

  obj.to_h
end

#query(&block) ⇒ Array<Event>

Passes a block to the database object and returns reconstructed Events.

Parameters:

  • block (Proc)

    the queries to act on the database object

Returns:

  • (Array<Event>)

    the reconstructed Event object or objects, if reconstruction was successful

Raises:


38
39
40
41
42
43
44
45
46
47
48
# File 'lib/australium/cache/event_cache.rb', line 38

def query(&block)
  events = instance_exec(&block)

  # Raise an exception if results are not in the expected format.
  raise CacheReadError unless events.is_a?(Mongo::Cursor)

  events = events.to_a

  # Convert from hashes to objects.
  events.map { |event| hash_to_obj(event) }
end

#store(game) ⇒ Object

Caches a complete Game.

Parameters:


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/australium/cache/event_cache.rb', line 80

def store(game)

  # If a MapLoad event exists with identical parameters for everything except the game hash, delete the previous
  # game data - as this indicates an invalid or incomplete log was stored.
  start_event = game.map_loads.first
  matches = db["MapLoad"].find(
    :server => start_event.server,
    :timestamp => start_event.timestamp,
    :game_id => { "$ne" => start_event.game_id }
  ).to_a
  matches.each do |match|
    invalid_game = match['game_id']
    puts "Removing data from game #{invalid_game} as an incomplete cache."
    @db.collections.each do |collection|
      next if collection.name.start_with?("system.")
      collection.remove(:game_id => invalid_game)
    end
  end

  to_store = game.events.map do |event|

    # Due to the enormous amount of repeated information, saving GameState objects is not a sane proposition at
    # this time. Until GameState objects can be stored more efficiently, they will not be inserted into databases.
    event.delete_field(:state) unless event.is_a?(GameEnd)

    obj_to_hash(event)

  end

  to_store.each do |event|
    db[event[:class]].update(
      {:server => event[:server],
       :game_id => event[:game_id],
       :line_number => event[:line_number]},
      event,
      {:upsert => true}
    )
  end

end