From 7dcb59333dbc6874d5c4fa6e02e51a9a65552ab1 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 15 Nov 2009 01:08:29 +0100 Subject: [PATCH] WIP draft of the complete query-for-session-contents implementation --- .../builder/applicablebuildertargettypes.hpp | 2 +- .../placement-index-query-resolver.hpp | 257 +++++++++++++++--- src/proc/mobject/session/placement-index.cpp | 1 + src/proc/mobject/session/query-resolver.hpp | 1 + src/proc/mobject/session/scope-query.hpp | 2 +- 5 files changed, 222 insertions(+), 41 deletions(-) diff --git a/src/proc/mobject/builder/applicablebuildertargettypes.hpp b/src/proc/mobject/builder/applicablebuildertargettypes.hpp index b02fb9d45..e1c223781 100644 --- a/src/proc/mobject/builder/applicablebuildertargettypes.hpp +++ b/src/proc/mobject/builder/applicablebuildertargettypes.hpp @@ -1,5 +1,5 @@ /* - ApplicableBuilderTargetTypes - definitinon header specifying all types treated by builder tools + ApplicableBuilderTargetTypes - definition header specifying all types treated by builder tools Copyright (C) Lumiera.org 2008, Hermann Vosseler diff --git a/src/proc/mobject/session/placement-index-query-resolver.hpp b/src/proc/mobject/session/placement-index-query-resolver.hpp index 2b5c5c203..b1c88c3ce 100644 --- a/src/proc/mobject/session/placement-index-query-resolver.hpp +++ b/src/proc/mobject/session/placement-index-query-resolver.hpp @@ -46,8 +46,9 @@ //#include //#include -//#include +#include //#include +#include namespace mobject { @@ -58,7 +59,7 @@ namespace session { // using lib::factory::RefcountFac; // using std::tr1::shared_ptr; -// using boost::scoped_ptr; + using boost::scoped_ptr; // using std::vector; @@ -72,8 +73,9 @@ namespace session { PPIdx index_; typedef PlacementIndex::ID PID; -////////////////////////////////////////////////////////////////TODO: moved in from PlacementIndex - typedef session::Goal::QueryID const& QID; +////////////////////////////////////////////////////////////////TODO: moved in from PlacementIndex + typedef Goal::QueryID QueryID; + typedef QueryID const& QID; template typename session::Query >::iterator @@ -83,7 +85,124 @@ namespace session { bool canHandleQuery(QID) const; ////////////////////////////////////////////////////////////////TODO: - + + + typedef PlacementIndex::iterator PIter; + + + /** Interface: strategy for exploring the structure */ + class Explorer + { + public: + virtual ~Explorer() { }; + virtual bool exhausted () =0; + virtual PlacementMO& operator() () =0; + }; + + /** + * Strategy: explore the structure + * just by following the given iterator; + * usually this yields an element's children + */ + class ChildExplorer + { + PIter tip_; + + bool + exhausted() + { + return !tip_; + } + + PlacementMO& + operator() () + { + REQUIRE (tip_); + PlacementMO& pos = *tip_; + ++tip_; + return pos; + } + + public: + ChildExplorer(PIter start) + : tip_(start) + { } + }; + + /** + * Strategy: explore the structure depth first. + * After returning an element, delve into the scope + * defined by this element and so on recursively. + */ + class DeepExplorer + { + PPIdx index_; + std::stack scopes_; + + bool + exhausted() + { + while (!scopes_.empty() && !scopes_.top()) + scopes_.pop(); + return scopes_.empty(); + } + + PlacementMO& + operator() () + { + REQUIRE (!scopes_.empty() && scopes_.top()); + PlacementMO& pos = *scopes_.top(); + ++scopes_.top(); + scopes_.push(index_->getReferrers(pos.getID())); + return pos; + } + + public: + DeepExplorer(PIter start, PPIdx idx) + : index_(idx) + { + scopes_.push(start); + } + }; + + + /** + * Strategy: explore the structure upwards, + * ascending until reaching the root element. + */ + class UpExplorer + { + PPIdx index_; + PlacementMO* tip_; + + bool + exhausted() + { + return !tip_; + } + + PlacementMO& + operator() () + { + REQUIRE (tip_); + PlacementMO& pos = *tip_; + tip_ = &index_->getScope(*tip_); + if (tip_ == &pos) + tip_ = 0; + return pos; + } + + public: + UpExplorer(PlacementMO& start, PPIdx idx) + : index_(idx) + , tip_(&start) + { } + }; + + typedef function ContentFilter; + typedef function ExplorerBuilder; + + /** * on query, an individual result set is prepared * to be explored by the invoking client code. @@ -91,36 +210,89 @@ namespace session { * obtained from the index, controlled by an * exploration strategy. */ - template struct ResultSet : Resolution { - DummySolutions solutions_; + typedef PlacementMO Val; - typedef typename Query::Cursor Cursor; + ContentFilter acceptable_; + ExplorerBuilder buildExploartion_; + scoped_ptr explore_; + + void + exploreNext (Result& res) + { + typedef typename Query::Cursor Cursor; + Cursor& cursor = static_cast (res); + + while (!explore_->exhausted() ) + { + Val& elm (*explore_()); + if (acceptable_(elm)) + { + cursor.point_at (elm); + return; + } + } + + ASSERT (explore_->exhausted()); + cursor.point_at (0); + } Result prepareResolution() { - Cursor cursor; - cursor.point_at (solutions_.next()); + explore_.reset (buildExploartion_()); + + Result cursor; + exploreNext (cursor); return cursor; } void nextResult(Result& pos) { - Cursor& cursor = static_cast (pos); - - if (solutions_.exhausted()) - cursor.point_at (0); - else - cursor.point_at (solutions_.next()); + exploreNext (pos); + return pos; } + + public: + ResultSet (ExplorerBuilder b + ,ContentFilter a) + : acceptable_(a) + , buildExploartion_(b) + , explore_() + { } }; + Explorer* + setupExploration (PID startID, Literal direction) + { + if (direction == "contents") + return new DeepExplorer(index_->getReferrers(startID), index_); + + else if (direction == "children") + return new ChildExplorer(index_->getReferrers(startID)); + + else if (direction == "parents") + return new UpExplorer(index_->getScope(startID),index_); + + else if (direction == "path") + return new UpExplorer(index_->find(startID),index_); + } + template - static Resolution* + void + defineHandling() + { + installResolutionCase( whenQueryingFor() + , bind (&PlacementIndexQueryResolver::resolutionFunction, + this, _1 ) + ); + } + + template + Resolution* resolutionFunction (Goal const& goal) { QID qID = goal.getQID(); @@ -132,39 +304,46 @@ namespace session { Literal direction = query.searchDirection(); PID scopeID = query.searchScope().getID(); //////////TICKET #411 - ///////////////////////////TODO: where to put the exploration strategy? statically, dynamically? - //////////////////////////////// note: direction == "parents" works completely different, based on index_->getScope(..) - - return new ResultSet(); + return new ResultSet( bind (&PlacementIndexQueryResolver::setupExploration, + this, scopeID, direction) + , getContentFilter(query) + ); + } + + template + ContentFilter + getContentFilter (QUERY query) + { + return query.contentFilter(); + } + + ContentFilter + getContentFilter (ScopeQuery) ///< especially queries for MObjects need not be filtered + { + ContentFilter acceptAllObjects = bind (val(true), _1); + return acceptAllObjects; + } + + template + static QueryID + whenQueryingFor() + { + QueryID qID = {Goal::DISCOVERY, getResultTypeID >()}; + return qID; } public: PlacementIndexQueryResolver (PPIdx theIndex) : index_(theIndex) { - Goal::QueryID case1 = {Goal::DISCOVERY, getResultTypeID()}; /////////////////TODO - Goal::QueryID case2 = {Goal::DISCOVERY, getResultTypeID()}; - - installResolutionCase(case1, &resolutionFunction ); - installResolutionCase(case2, &resolutionFunction ); + defineHandling(); + defineHandling(); + defineHandling(); } }; - /** @todo use query-resolver-test as an example..... - * return a result set object derived from Resolution - * For the additional type filtering: build a filter iterator, - * using a type-filtering predicate, based on Placement#isCompatible - */ - template - inline typename session::Query >::iterator - PlacementIndexQueryResolver::query (PlacementMO& scope) const - { - UNIMPLEMENTED ("actually run the containment query"); - } - - bool PlacementIndexQueryResolver::canHandleQuery (QID qID) const { diff --git a/src/proc/mobject/session/placement-index.cpp b/src/proc/mobject/session/placement-index.cpp index b114e1a4e..3c236feea 100644 --- a/src/proc/mobject/session/placement-index.cpp +++ b/src/proc/mobject/session/placement-index.cpp @@ -111,6 +111,7 @@ namespace session { PlacementIndex::getScope (ID) const { UNIMPLEMENTED ("Secondary core operation of PlacmentIndex: find the 'parent' Placement by using the Placement relation index"); + /// decision: root is his own scope } diff --git a/src/proc/mobject/session/query-resolver.hpp b/src/proc/mobject/session/query-resolver.hpp index 4328d899d..62a8980d4 100644 --- a/src/proc/mobject/session/query-resolver.hpp +++ b/src/proc/mobject/session/query-resolver.hpp @@ -179,6 +179,7 @@ namespace session { RES* operator->() { return & access(); } void point_at(RES* r){ Goal::Result::point_at(r);} + void point_at(RES& r){ Goal::Result::point_at(&r);} }; diff --git a/src/proc/mobject/session/scope-query.hpp b/src/proc/mobject/session/scope-query.hpp index 72e895851..76db0b088 100644 --- a/src/proc/mobject/session/scope-query.hpp +++ b/src/proc/mobject/session/scope-query.hpp @@ -80,7 +80,7 @@ namespace session { typedef typename _Query::iterator _QIter; - typedef typename _QIter::reference Val; + typedef typename PlacementMO const& Val; public: