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:
Fischlurch 2012-12-17 23:17:32 +01:00
parent 1bde72cccf
commit 5cddc57932
5 changed files with 144 additions and 27 deletions

View file

@ -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

View file

@ -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;

View file

@ -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_)

View file

@ -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

View file

@ -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