WIP extend query with a warpper for indexing and ordering
...to extract the syntetic ordering from DefsRegistry and make that a responsibility of the (internal) syntactic representation of the query. doesn't pass the compiler yet
This commit is contained in:
parent
1bde72cccf
commit
5cddc57932
5 changed files with 144 additions and 27 deletions
|
|
@ -35,6 +35,7 @@
|
|||
#include "lib/util.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <tr1/memory>
|
||||
#include <typeinfo>
|
||||
#include <cctype>
|
||||
|
|
@ -55,7 +56,9 @@ namespace lumiera {
|
|||
|
||||
class Goal;
|
||||
class Resolution;
|
||||
class QueryResolver;
|
||||
class QueryResolver;
|
||||
class QueryKey;
|
||||
|
||||
|
||||
/** Allow for taking ownership of a result set */
|
||||
typedef std::tr1::shared_ptr<Resolution> PReso;
|
||||
|
|
@ -253,10 +256,10 @@ namespace lumiera {
|
|||
rebuild() const;
|
||||
|
||||
string
|
||||
extractID (Symbol predicate) const
|
||||
{
|
||||
return this->rebuild().extractID (predicate);
|
||||
}
|
||||
extractID (Symbol predicate) const;
|
||||
|
||||
operator QueryKey() const;
|
||||
|
||||
|
||||
|
||||
/* results retrieval */
|
||||
|
|
@ -298,6 +301,55 @@ namespace lumiera {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for indexing and ordering.
|
||||
* Defines a synthetic totally ordered index value.
|
||||
* Implicitly convertible to and from Query instances.
|
||||
*/
|
||||
class QueryKey
|
||||
: boost::totally_ordered< QueryKey>
|
||||
{
|
||||
Goal::QueryID id_;
|
||||
lib::QueryText def_;
|
||||
|
||||
public:
|
||||
QueryKey (Goal::QueryID id, lib::QueryText def)
|
||||
: id_(id)
|
||||
, def_(q)
|
||||
{ }
|
||||
|
||||
// default copyable
|
||||
|
||||
template<class RES>
|
||||
operator Query<RES>() const
|
||||
{
|
||||
return Query<RES>::build().withConditions(def_);
|
||||
}
|
||||
|
||||
uint
|
||||
degree() const
|
||||
{
|
||||
return def_.degree();
|
||||
}
|
||||
|
||||
|
||||
friend bool
|
||||
operator< (QueryKey const& q1, QueryKey const& q2)
|
||||
{
|
||||
return q1.degree() < q2.degree();
|
||||
}
|
||||
|
||||
friend size_t
|
||||
hash_value (QueryKey const& q)
|
||||
{
|
||||
return hash_value (q.def_); /////////////////TODO include the QueryID into the generated hash?
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper for establishing,
|
||||
* reworking and remolding queries.
|
||||
|
|
@ -360,19 +412,54 @@ namespace lumiera {
|
|||
return *this;
|
||||
}
|
||||
|
||||
Builder&
|
||||
withConditions (string additionalQueryPredicates)
|
||||
{
|
||||
lib::query::appendTerms(this->predicateForm_, additionalQueryPredicates);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template<class RES>
|
||||
typename Query<RES>::Builder
|
||||
inline typename Query<RES>::Builder
|
||||
Query<RES>::rebuild() const
|
||||
{
|
||||
return Builder(this->id_, this->def_);
|
||||
}
|
||||
|
||||
|
||||
/** convenience shortcut to extract a desired name-ID.
|
||||
* @todo used extensively for the mock implementation of query resolution.
|
||||
* For real resolution queries, such a function is quite nonsensical.
|
||||
* To be revisited and (likely) to be removed on the long run
|
||||
* @see Query::Builder#extractID
|
||||
*/
|
||||
template<class RES>
|
||||
inline string
|
||||
Query<RES>::extractID (Symbol predicate) const
|
||||
{
|
||||
return this->rebuild().extractID (predicate);
|
||||
}
|
||||
|
||||
|
||||
/** automatic conversion from Query to QueryKey for indexing and ordering.
|
||||
* By defining a parameter of type QueryKey, any provided Query will be
|
||||
* automatically transformed into an generic representation usable for
|
||||
* ordered storage in sets, maps and for generation of metrics.
|
||||
*/
|
||||
template<class RES>
|
||||
Query<RES>::operator QueryKey() const
|
||||
{
|
||||
return QueryKey (this->id_, this->def_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace lumiera
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
** For the standard use-case within the session / Proc-Layer, this is performed for the
|
||||
** core MObject types, alongside with the definition of the generic config-query-resolver.
|
||||
**
|
||||
** @see config-resolver.cpp definition of the explicit specialisiations for the session
|
||||
** @see config-resolver.cpp definition of the explicit specialisations for the session
|
||||
** @see proc::ConfigResolver
|
||||
**
|
||||
*/
|
||||
|
|
@ -139,11 +139,10 @@ namespace query {
|
|||
return res;
|
||||
else
|
||||
res = create (capabilities); // not yet known as default, create new
|
||||
|
||||
UNIMPLEMENTED("String representation of queries, here just for diagnostics");
|
||||
|
||||
if (!res)
|
||||
throw lumiera::error::Config (_Fmt("The following Query could not be resolved: %s.")
|
||||
% "TODO"//capabilities.asKey()////////////////////////////////////////////////////////////////////////////////////////////TODO
|
||||
% capabilities.rebuild().asKey()
|
||||
, LUMIERA_ERROR_CAPABILITY_QUERY );
|
||||
else
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -23,11 +23,19 @@
|
|||
|
||||
/** @file defs-registry.hpp
|
||||
** A piece of implementation code factored out into a separate header (include).
|
||||
** Only used in defs-manager.cpp and for the unit tests. We can't place it into
|
||||
** a separate compilation unit, because defs-manager.cpp defines some explicit
|
||||
** Only used through defs-manager-impl.hpp and for the unit tests. We can't place it
|
||||
** into a separate compilation unit, because config-resolver.cpp defines some explicit
|
||||
** template instantiation, which cause the different Slots of the DefsrRegistry#table_
|
||||
** to be filled with data and defaults for the specific Types.
|
||||
**
|
||||
** Basically, this piece of code defines a specialised index / storage table to hold
|
||||
** Queries-for-default objects. This allows to remember what actually was used as
|
||||
** "default" solution for some query and to oder possible default solutions.
|
||||
** @remarks as of 2012, we're still using a fake implementation of the resolution,
|
||||
** no real resolution engine. While the basic idea of this "defaults registry"
|
||||
** is likely to stay, the actual order relation and maybe even the components
|
||||
** to be stored in this registry might be subject to change.
|
||||
**
|
||||
** @see mobject::session::DefsManager
|
||||
** @see DefsRegistryImpl_test
|
||||
**
|
||||
|
|
@ -44,13 +52,13 @@
|
|||
#include "lib/util.hpp"
|
||||
#include "lib/util-foreach.hpp"
|
||||
#include "lib/sync-classlock.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/query-util.hpp"
|
||||
#include "common/query.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <tr1/memory>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
|
||||
|
|
@ -70,8 +78,10 @@ namespace query {
|
|||
namespace impl {
|
||||
|
||||
namespace {
|
||||
using util::_Fmt;
|
||||
|
||||
uint maxSlots (0); ///< number of different registered Types
|
||||
format dumpRecord ("%2i| %64s --> %s\n");
|
||||
_Fmt dumpRecord ("%2i| %64s --> %s\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -95,7 +105,7 @@ namespace query {
|
|||
Query<TAR> query;
|
||||
weak_ptr<TAR> objRef;
|
||||
|
||||
Record (const Query<TAR>& q, const P<TAR>& obj)
|
||||
Record (Query<TAR> const& q, P<TAR> const& obj)
|
||||
: degree (lib::query::countPred ("TODO")),//q)),////////////////////////////////////////////////////////////////////////////////////////////TODO
|
||||
query (q),
|
||||
objRef (obj)
|
||||
|
|
@ -106,13 +116,13 @@ namespace query {
|
|||
|
||||
struct Search ///< Functor searching for a specific object
|
||||
{
|
||||
Search (const P<TAR>& obj)
|
||||
Search (P<TAR> const& obj)
|
||||
: obj_(obj) { }
|
||||
|
||||
const P<TAR>& obj_;
|
||||
P<TAR> const& obj_;
|
||||
|
||||
bool
|
||||
operator() (const Record& rec)
|
||||
operator() (Record const& rec)
|
||||
{
|
||||
P<TAR> storedObj (rec.objRef.lock());
|
||||
return storedObj && (storedObj == obj_);
|
||||
|
|
@ -131,7 +141,7 @@ namespace query {
|
|||
}
|
||||
};
|
||||
|
||||
operator string () const { return str (dumpRecord % degree % query % dumpObj()); }
|
||||
operator string () const { return dumpRecord % degree % query % dumpObj(); }
|
||||
string dumpObj () const { P<TAR> o (objRef.lock()); return o? string(*o):"dead"; }
|
||||
};
|
||||
|
||||
|
|
@ -141,7 +151,8 @@ namespace query {
|
|||
* separate tree (set) of registry entries
|
||||
*/
|
||||
template<class TAR>
|
||||
struct Slot : public TableEntry
|
||||
struct Slot
|
||||
: public TableEntry
|
||||
{
|
||||
typedef typename Record<TAR>::OrderRelation Ordering;
|
||||
typedef std::set<Record<TAR>, Ordering> Registry;
|
||||
|
|
@ -195,7 +206,8 @@ namespace query {
|
|||
* @todo as of 3/2008 the real query implementation is missing, and the
|
||||
* exact behaviour has to be defined.
|
||||
*/
|
||||
class DefsRegistry : private boost::noncopyable
|
||||
class DefsRegistry
|
||||
: boost::noncopyable
|
||||
{
|
||||
Table table_;
|
||||
|
||||
|
|
@ -223,7 +235,8 @@ namespace query {
|
|||
operator++ (); // init to first element (or to null if empty)
|
||||
}
|
||||
|
||||
P<TAR> findNext () throw()
|
||||
P<TAR>
|
||||
findNext () ///< EX_FREE
|
||||
{
|
||||
while (!next)
|
||||
{
|
||||
|
|
@ -256,7 +269,8 @@ namespace query {
|
|||
* @note none of the queries will be evaluated (we're just counting predicates)
|
||||
*/
|
||||
template<class TAR>
|
||||
Iter<TAR> candidates (const Query<TAR>& query)
|
||||
Iter<TAR>
|
||||
candidates (Query<TAR> const& query)
|
||||
{
|
||||
P<TAR> dummy;
|
||||
Record<TAR> entry (query, dummy);
|
||||
|
|
@ -282,7 +296,8 @@ namespace query {
|
|||
* case, also the param obj shared-ptr is rebound!
|
||||
*/
|
||||
template<class TAR>
|
||||
bool put (P<TAR>& obj, const Query<TAR>& query)
|
||||
bool
|
||||
put (P<TAR>& obj, Query<TAR> const& query)
|
||||
{
|
||||
Record<TAR> entry (query, obj);
|
||||
typedef typename Slot<TAR>::Registry Registry;
|
||||
|
|
@ -311,7 +326,8 @@ namespace query {
|
|||
* @return false if the object wasn't registered at all.
|
||||
*/
|
||||
template<class TAR>
|
||||
bool forget (const P<TAR>& obj)
|
||||
bool
|
||||
forget (P<TAR> const& obj)
|
||||
{
|
||||
typedef typename Slot<TAR>::Registry Registry;
|
||||
typedef typename Record<TAR>::Search SearchFunc;
|
||||
|
|
@ -325,7 +341,8 @@ namespace query {
|
|||
* @note to use it, your objects need an operator string()
|
||||
*/
|
||||
template<class TAR>
|
||||
string dump()
|
||||
string
|
||||
dump ()
|
||||
{
|
||||
string res;
|
||||
util::for_each ( Slot<TAR>::access(table_)
|
||||
|
|
|
|||
|
|
@ -138,6 +138,18 @@ namespace lib {
|
|||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
/** @note preliminary implementation without any syntax checks
|
||||
* @return a conjunction of the predicates
|
||||
*/
|
||||
string
|
||||
appendTerms (string const& pred1, string const& pred2)
|
||||
{
|
||||
string res(pred1);
|
||||
return res + ", " + pred2;
|
||||
}
|
||||
|
||||
|
||||
} // namespace query
|
||||
|
||||
} // namespace lib
|
||||
|
|
|
|||
|
|
@ -58,10 +58,12 @@ namespace lib {
|
|||
uint countPred (const string&);
|
||||
|
||||
|
||||
const string extractID (Symbol, const string& termString);
|
||||
const string extractID (Symbol, string const& termString);
|
||||
|
||||
const string removeTerm (Symbol, string& termString);
|
||||
|
||||
string appendTerms (string const& pred1, string const& pred2);
|
||||
|
||||
|
||||
template<typename TY>
|
||||
const string
|
||||
|
|
|
|||
Loading…
Reference in a new issue