77 #ifndef LUMIERA_ADVICE_INDEX_H 78 #define LUMIERA_ADVICE_INDEX_H 90 #include <boost/operators.hpp> 91 #include <unordered_map> 99 using std::placeholders::_1;
100 using std::unordered_map;
146 : pair<Binding::Matcher, POA*>
147 , boost::equality_comparable<Entry, POA,
148 boost::equality_comparable<Entry>
153 : pair<Binding::Matcher, POA*> (elm.getMatcher(), &elm)
159 operator string() const
161 return "E-" +hash_value(this->first) +
"--> "+ this->second ;
167 return a.second == b.second;
171 operator== (
Entry const& a, POA
const& p)
173 return a.second == &p;
178 typedef vector<Entry> EntryList;
179 typedef typename EntryList::iterator EIter;
195 REQUIRE (!contains (elm),
"Duplicate entry");
196 try { elms_.push_back (
Entry(elm)); }
198 catch(std::bad_alloc&)
200 throw error::Fatal(
"AdviceSystem failure due to exhausted memory");
205 overwrite (POA
const& oldRef, POA& newElm)
207 EIter pos = std::find (elms_.begin(),elms_.end(), oldRef);
208 REQUIRE (pos!=elms_.end(),
"Attempt to overwrite an entry which isn't there.");
209 REQUIRE_IF (&oldRef != &newElm, !contains (newElm),
"Duplicate entry");
211 *pos =
Entry(newElm);
213 REQUIRE_IF (&oldRef != &newElm, !contains (oldRef),
"Duplicate entry");
217 remove (POA
const& refElm)
219 EIter pos = std::find (elms_.begin(),elms_.end(), refElm);
220 if (pos!=elms_.end())
223 ENSURE (!contains (refElm),
"Duplicate entry");
227 contains (POA
const& refElm)
229 for (EIter i=elms_.begin(); i!=elms_.end(); ++i)
230 if (*i == refElm)
return true;
234 operator string() const
236 string dump{
"elmList("+toString(elms_.size())+
")\n"};
237 for (
auto const&
entry : elms_)
238 dump +=
"E...:"+
entry+
"\n";
245 return eachElm (elms_);
254 find_latest_solution (POA& requestElm)
256 typedef typename EntryList::reverse_iterator RIter;
258 for (RIter ii=this->elms_.rbegin();
259 ii!=this->elms_.rend();
261 if (ii->first.matches (pattern))
268 publish_latest_solution (POA& requestElm)
270 POA* solution = find_latest_solution (requestElm);
274 requestElm.setSolution (solution);
276 requestElm.setSolution ( NULL );
285 publish_all_solutions (POA& provisionElm)
288 for (EIter ii=this->elms_.begin();
289 ii!=this->elms_.end();
291 if (pattern.matches (ii->first))
294 ii->second->setSolution (&provisionElm);
298 retract_all_solutions (POA
const& oldProv,
ProvisionCluster& possibleReplacementSolutions)
301 for (EIter ii=this->elms_.begin();
302 ii!=this->elms_.end();
304 if (pattern.matches (ii->first))
307 possibleReplacementSolutions.publish_latest_solution (*(ii->second));
311 rewrite_all_solutions (POA
const& oldProv, POA& newProv,
ProvisionCluster& possibleReplacementSolutions)
315 for (EIter ii=this->elms_.begin();
316 ii!=this->elms_.end();
318 if (newPattern.matches (ii->first))
319 ii->second->setSolution (&newProv);
321 if (oldPattern.matches (ii->first))
322 possibleReplacementSolutions.publish_latest_solution (*(ii->second));
330 typedef unordered_map<HashVal, RequestCluster> RTable;
331 typedef unordered_map<HashVal, ProvisionCluster> PTable;
333 mutable RTable requestEntries_;
334 mutable PTable provisionEntries_;
341 addRequest (POA&
entry)
343 HashVal key (hash_value(entry));
344 requestEntries_[key].append (entry);
345 provisionEntries_[key].publish_latest_solution (entry);
357 HashVal nKey (hash_value(entry));
360 requestEntries_[nKey].append (entry);
361 requestEntries_[oKey].remove (entry);
365 requestEntries_[nKey].overwrite (entry, entry);
367 provisionEntries_[nKey].publish_latest_solution (entry);
371 removeRequest (POA
const& refEntry)
373 HashVal oKey (hash_value(refEntry));
374 requestEntries_[oKey].remove (refEntry);
379 addProvision (POA& entry)
381 HashVal key (hash_value(entry));
382 provisionEntries_[key].append (entry);
383 requestEntries_[key].publish_all_solutions (entry);
387 modifyProvision (POA
const& oldRef, POA& newEntry)
389 HashVal oKey (hash_value(oldRef));
390 HashVal nKey (hash_value(newEntry));
393 provisionEntries_[nKey].append (newEntry);
394 provisionEntries_[oKey].remove (oldRef);
395 requestEntries_[nKey].publish_all_solutions (newEntry);
396 requestEntries_[oKey].retract_all_solutions (oldRef, provisionEntries_[oKey]);
400 provisionEntries_[nKey].overwrite (oldRef, newEntry);
401 requestEntries_[nKey].rewrite_all_solutions (oldRef,newEntry, provisionEntries_[nKey]);
406 removeProvision (POA
const& refEntry)
408 HashVal key (hash_value(refEntry));
409 provisionEntries_[key].remove (refEntry);
410 requestEntries_[key].retract_all_solutions (refEntry, provisionEntries_[key]);
421 WARN (library,
"Purging Advice Binding Index...");
422 requestEntries_.clear();
423 provisionEntries_.clear();
436 return request_count() + provision_count();
440 request_count()
const 446 provision_count()
const 452 hasRequest (POA
const& refEntry)
const 454 return requestEntries_[hash_value(refEntry)].contains (refEntry);
458 hasProvision (POA
const& refEntry)
const 460 return provisionEntries_[hash_value(refEntry)].contains (refEntry);
478 void verify_Entry (Entry
const&,
HashVal)
const;
479 void verify_Request (Entry
const&,
HashVal)
const;
503 ,LUMIERA_ERROR_INDEX_CORRUPTED}
521 typedef typename RTable::const_iterator RTIter;
522 typedef typename PTable::const_iterator PTIter;
525 for (PTIter ii =provisionEntries_.begin();
526 ii != provisionEntries_.end(); ++ii)
529 Cluster& clu = unConst(ii->second);
530 for_each (clu.allElms(), &Index::verify_Entry,
this, _1, hash);
532 for (RTIter ii=requestEntries_.begin();
533 ii != requestEntries_.end(); ++ii)
536 Cluster& clu = unConst(ii->second);
537 for_each (clu.allElms(), &Index::verify_Request,
this, _1, hash);
542 catch(SelfCheckFailure& failure)
545 ERROR (library,
"%s", failure.what());
552 #define VERIFY(_CHECK_, DESCRIPTION) \ 554 throw SelfCheckFailure ((DESCRIPTION)); 561 VERIFY (hash == hash_value(e.first),
"Wrong bucket, hash doesn't match bucket");
562 VERIFY (e.second,
"Invalid Entry: back-link is NULL");
569 verify_Entry (e,hash);
570 POA& request = *(e.second);
571 const POA* solution (request.getSolution());
572 if (solution && hasProvision(*solution))
574 POA* currentSolution = provisionEntries_[hash].find_latest_solution (request);
575 VERIFY (e.first.matches (solution->getMatcher()),
"stored advice solution not supported by binding match");
576 VERIFY (
bool(currentSolution),
"unable to reproduce stored solution with the current provisions")
577 VERIFY (solution == currentSolution,
"stored advice solution isn't the topmost solution for this request")
Functor object for matching against another Binding.
AnyPair entry(Query< TY > const &query, typename WrapReturn< TY >::Wrapper &obj)
helper to simplify creating mock table entries, wrapped correctly
inline string literal This is a marker type to indicate that
This header is for including and configuring NoBug.
static size_t sumClusters(IT ii)
internal: sum element count over all clusters in the given hashtable
Derived specific exceptions within Lumiera's exception hierarchy.
A pattern to define and identify a specific attachment to the Advice system.
Marker types to indicate a literal string and a Symbol.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
bool isValid() const
validity self-check
lumiera_err lumiera_error(void)
Get and clear current error state.
void for_each(CON const &elements, FUN function, P1 &&bind1, ARGS &&...args)
Accept binding for arbitrary function arguments.
_SeqT< CON >::Range eachElm(CON &coll)
Lumiera error handling (C++ interface).
size_t HashVal
a STL compatible hash value
Lumiera public interface.
void modifyRequest(HashVal oKey, POA &entry)
Accessing a STL element range through a Lumiera forward iterator, An instance of this iterator adapte...
Preconfigured adapters for some STL container standard usage situations.
Index datastructure for organising advice solutions.
Perform operations "for each element" of a collection.
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container
_MapIterT< IT >::ValIter eachVal(IT const &begin, IT const &end)
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.