Fawkes API  Fawkes Development Version
computables_manager.cpp
1 /***************************************************************************
2  * computables_manager.cpp - Class managing registered computables and
3  * checking if any computables are invoced by a query
4  *
5  * Created: 6:37:45 PM 2016
6  * Copyright 2016 Frederik Zwilling
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include "computables_manager.h"
23 
24 #include <core/exception.h>
25 #include <plugins/robot-memory/robot_memory.h>
26 
27 #include <chrono>
28 
29 /** @class ComputablesManager computables_manager.h
30  * This class manages registering computables and can check
31  * if any computables are invoced by a query.
32  * @author Frederik Zwilling
33  */
34 
35 using namespace fawkes;
36 using namespace mongo;
37 
38 /**
39  * Constructor for class managing computables with refereces to plugin objects
40  * @param config Configuration
41  * @param robot_memory Robot Memory
42  */
44 : config_(config),
45  robot_memory_(robot_memory),
46  matching_test_collection_("robmem.computables_matching")
47 {
48  try {
49  matching_test_collection_ =
50  config_->get_string("/plugins/robot-memory/database") + ".computables_matching";
51  } catch (Exception &e) {
52  }
53 
54  srand(time(NULL));
55 }
56 
57 ComputablesManager::~ComputablesManager()
58 {
59 }
60 
61 /**
62  * Remove previously registered computable
63  * @param computable The computable to remove
64  */
65 void
67 {
68  for (std::list<Computable *>::iterator it = computables.begin(); it != computables.end(); ++it) {
69  if ((*it) == computable) {
70  Computable *comp = *it;
71  computables.erase(it);
72  delete comp;
73  return;
74  }
75  }
76 }
77 
78 /**
79  * Checks if computable knowledge is queried and calls the compute functions in this case
80  * @param query The query that might ask for computable knowledge
81  * @param collection The collection that is querried
82  * @return Were computed documents added?
83  */
84 bool
85 ComputablesManager::check_and_compute(mongo::Query query, std::string collection)
86 {
87  //check if computation result of the query is already cached
88  for (std::map<std::tuple<std::string, std::string>, long long>::iterator it =
89  cached_querries_.begin();
90  it != cached_querries_.end();
91  ++it) {
92  if (collection == std::get<0>(it->first) && query.toString() == std::get<1>(it->first)) {
93  return false;
94  }
95  }
96  if (collection.find(matching_test_collection_) != std::string::npos)
97  return false; //not necessary for matching test itself
98  bool added_computed_docs = false;
99  //check if the query is matched by the computable identifyer
100  //to do that we just insert the query as if it would be a document and query for it with the computable identifiers
101  std::string current_test_collection = matching_test_collection_ + std::to_string(rand());
102  robot_memory_->insert(query.obj, current_test_collection);
103  for (std::list<Computable *>::iterator it = computables.begin(); it != computables.end(); ++it) {
104  if (collection == (*it)->get_collection()
105  && robot_memory_->query((*it)->get_query(), current_test_collection)->more()) {
106  std::list<BSONObj> computed_docs_list = (*it)->compute(query.obj);
107  if (!computed_docs_list.empty()) {
108  //move list into vector
109  std::vector<BSONObj> computed_docs_vector{
110  std::make_move_iterator(std::begin(computed_docs_list)),
111  std::make_move_iterator(std::end(computed_docs_list))};
112  //remember how long a query is cached:
113  long long cached_until =
114  computed_docs_vector[0].getField("_robmem_info").Obj().getField("cached_until").Long();
115  cached_querries_[std::make_tuple(collection, query.toString())] = cached_until;
116  //TODO: fix minor problem: equivalent queries in different order jield unequal strings
117  robot_memory_->insert(computed_docs_vector, (*it)->get_collection());
118  added_computed_docs = true;
119  }
120  }
121  }
122  robot_memory_->drop_collection(current_test_collection);
123  return added_computed_docs;
124 }
125 
126 /**
127  * Clean up all collections containing documents computed on demand
128  */
129 void
131 {
132  long long current_time_ms =
133  std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
134  for (std::map<std::tuple<std::string, std::string>, long long>::iterator it =
135  cached_querries_.begin();
136  it != cached_querries_.end();
137  ++it) {
138  if (current_time_ms > it->second) {
139  robot_memory_->remove(BSON("_robmem_info.computed" << true << "_robmem_info.cached_until"
140  << BSON("$lt" << current_time_ms)),
141  std::get<0>(it->first));
142  cached_querries_.erase(it->first);
143  }
144  }
145 }
QResCursor query(mongo::Query query, const std::string &collection="")
Query information from the robot memory.
int remove(mongo::Query query, const std::string &collection="")
Remove documents from the robot memory.
Fawkes library namespace.
void cleanup_computed_docs()
Clean up all collections containing documents computed on demand.
Class holding information for a single computable this class also enhances computed documents by addi...
Definition: computable.h:29
ComputablesManager(fawkes::Configuration *config, RobotMemory *robot_memory)
Constructor for class managing computables with refereces to plugin objects.
int insert(mongo::BSONObj obj, const std::string &collection="")
Inserts a document into the robot memory.
int drop_collection(const std::string &collection)
Drop (= remove) a whole collection and all documents inside it.
Base class for exceptions in Fawkes.
Definition: exception.h:35
void remove_computable(Computable *computable)
Remove previously registered computable.
Access to the robot memory based on mongodb.
Definition: robot_memory.h:48
Interface for configuration handling.
Definition: config.h:64
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
bool check_and_compute(mongo::Query query, std::string collection)
Checks if computable knowledge is queried and calls the compute functions in this case.