zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #18104
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/count-opt into lp:zorba.
Commit message:
Introduced generic framework for optimizing fn:count() during runtime: Virtual PlanIterator::count() method provides the base (unoptimized) implementation of fn:count(). This base method is redefined by other plan iterators who have a way of returning the cardinality of their result sequence without actually computing the full result sequence.
Requested reviews:
Markos Zaharioudakis (markos-za)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/count-opt/+merge/148586
Introduced generic framework for optimizing fn:count() during runtime: Virtual PlanIterator::count() method provides the base (unoptimized) implementation of fn:count(). This base method is redefined by other plan iterators who have a way of returning the cardinality of their result sequence without actually computing the full result sequence.
--
https://code.launchpad.net/~zorba-coders/zorba/count-opt/+merge/148586
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/functions/func_sequences_impl.cpp'
--- src/functions/func_sequences_impl.cpp 2013-01-22 18:48:07 +0000
+++ src/functions/func_sequences_impl.cpp 2013-02-15 00:39:22 +0000
@@ -818,36 +818,7 @@
{
const std::type_info& counted_type = typeid(*argv[0]);
- if (typeid(ZorbaCollectionIterator) == counted_type)
- {
- ZorbaCollectionIterator& collection =
- static_cast<ZorbaCollectionIterator&>(*argv[0]);
-
- if (collection.isCountOptimizable())
- {
- return new CountCollectionIterator(
- sctx,
- loc,
- collection.getChildren(),
- (
- collection.isDynamic()
- ? CountCollectionIterator::ZORBADYNAMIC
- : CountCollectionIterator::ZORBASTATIC
- )
- );
- }
- }
- else if (typeid(FnCollectionIterator) == counted_type)
- {
- FnCollectionIterator& collection =
- static_cast<FnCollectionIterator&>(*argv[0]);
-
- return new CountCollectionIterator(sctx,
- loc,
- collection.getChildren(),
- CountCollectionIterator::W3C);
- }
- else if (typeid(ProbeIndexPointValueIterator) == counted_type)
+ if (typeid(ProbeIndexPointValueIterator) == counted_type)
{
ProbeIndexPointValueIterator& lIter
= static_cast<ProbeIndexPointValueIterator&>(*argv[0]);
=== modified file 'src/runtime/base/plan_iterator.cpp'
--- src/runtime/base/plan_iterator.cpp 2012-09-19 21:16:15 +0000
+++ src/runtime/base/plan_iterator.cpp 2013-02-15 00:39:22 +0000
@@ -23,6 +23,12 @@
#include "runtime/util/flowctl_exception.h"
+#include "system/globalenv.h"
+
+#include "store/api/store.h"
+#include "store/api/item_factory.h"
+
+
namespace zorba
{
@@ -93,6 +99,22 @@
}
+void PlanIterator::count(store::Item_t& result, PlanState& planState) const
+{
+ store::Item_t item;
+ ulong count = 0;
+
+ while (consumeNext(item, this, planState))
+ {
+ ++count;
+ }
+
+ GENV_ITEMFACTORY->createInteger(result, Integer(count));
+}
+
+
+#if ZORBA_BATCHING_TYPE == 0
+
#ifndef NDEBUG
bool PlanIterator::consumeNext(
@@ -120,6 +142,7 @@
}
#endif
+#endif
} // namespace zorba
/* vim:set et sw=2 ts=2: */
=== modified file 'src/runtime/base/plan_iterator.h'
--- src/runtime/base/plan_iterator.h 2012-09-19 21:16:15 +0000
+++ src/runtime/base/plan_iterator.h 2013-02-15 00:39:22 +0000
@@ -111,6 +111,7 @@
theBlock : Pointer to the memory block that stores the local state of
each individual plan iterator.
theBlockSize : Size (in bytes) of the block.
+
theHasToQuit : Boolean that indicates if the query execution has to quit.
Checking this value is done in each consumeNext call,
i.e. between every two iterator next calls. This value is
@@ -128,9 +129,6 @@
uint32_t theMaxStackDepth;
- // TODO this guy should become const because nothing can change anymore during
- // runtime. We need to make all accessor in the control block and static context
- // (see also shortcut below) const before doing that
CompilerCB * theCompilerCB;
XQueryImpl * theQuery;
@@ -168,16 +166,18 @@
static const uint32_t DUFFS_ALLOCATE_RESOURCES = 0;
private:
- uint32_t theDuffsLine;
+ uint32_t theDuffsLine;
public:
#if ZORBA_BATCHING_TYPE == 1
public:
- uint32_t theCurrItem;
- store::Item_t theBatch[ZORBA_BATCHING_BATCHSIZE];
+ bool theIsDone;
+ store::Item_t * theEndItem;
+ store::Item_t * theCurrItem;
+ store::Item_t theBatch[ZORBA_BATCHING_BATCHSIZE];
#endif
#ifndef NDEBUG
- bool theIsOpened;
+ bool theIsOpened;
#endif
public:
@@ -185,16 +185,19 @@
:
theDuffsLine(DUFFS_ALLOCATE_RESOURCES)
#if ZORBA_BATCHING_TYPE == 1
- , theCurrItem(ZORBA_BATCHING_BATCHSIZE)
+ , theIsDone(false)
+ , theEndItem(NULL)
+ , theCurrItem(NULL)
#endif
#ifndef NDEBUG
, theIsOpened(false)
#endif
- {}
+ {
+ }
~PlanIteratorState() {}
- void setDuffsLine(uint32_t aVal) { theDuffsLine = aVal; }
+ void setDuffsLine(uint32_t v) { theDuffsLine = v; }
uint32_t getDuffsLine() const { return theDuffsLine; }
@@ -210,13 +213,7 @@
* Each subclass implementation of this method must call the init() method of
* their parent class explicitly in order to guarantee proper initialization.
*/
- void init(PlanState&)
- {
- theDuffsLine = DUFFS_ALLOCATE_RESOURCES;
-#if ZORBA_BATCHING_TYPE == 1
- theCurrItem = ZORBA_BATCHING_BATCHSIZE;
-#endif
- }
+ void init(PlanState& s) { reset(s); }
/**
* Reset the current state object.
@@ -234,10 +231,9 @@
{
theDuffsLine = DUFFS_ALLOCATE_RESOURCES;
#if ZORBA_BATCHING_TYPE == 1
- theCurrItem = ZORBA_BATCHING_BATCHSIZE;
- // seeting the first item to NULL only is sufficient so
- // that produceNext knows that it's not finished yet
- theBatch[0] = NULL;
+ theIsDone = false;
+ theEndItem = NULL;
+ theCurrItem = NULL;
#endif
}
};
@@ -286,12 +282,6 @@
}
};
-#if ZORBA_BATCHING_TYPE == 1
-
-#error "Batching not implemented with the new iterator contract."
-
-#endif
-
/*******************************************************************************
Base class of all plan iterators.
@@ -393,6 +383,11 @@
*/
virtual void close(PlanState& planState) = 0;
+ /**
+ *
+ */
+ virtual void count(store::Item_t& result, PlanState& planState) const;
+
#if ZORBA_BATCHING_TYPE == 1
@@ -411,33 +406,34 @@
* batch buffer have been consumed already, then it makes the iterator produce
* its next batch of results and retrieves the 1st item from this new batch.
*/
- static store::Item_t consumeNext(
+ static bool consumeNext(
store::Item_t& result,
const PlanIterator* iter,
PlanState& planState)
{
- try
- {
- // use the given iterator's planstate to access it's batch
- PlanIteratorState* lState =
- StateTraitsImpl<PlanIteratorState>::getState(planState, iter->getStateOffset());
-
- if ( lState->theCurrItem == ZORBA_BATCHING_BATCHSIZE )
- {
- iter->produceNext(planState);
- lState->theCurrItem = 0;
- }
- }
- catch(ZorbaException& e)
- {
- if(loc != NULL)
- {
- set_source(e, loc);
- throw;
- }
- }
-
- return lState->theBatch[lState->theCurrItem++];
+ PlanIteratorState* state =
+ StateTraitsImpl<PlanIteratorState>::getState(planState, iter->getStateOffset());
+
+ if (state->theCurrItem == state->theEndItem)
+ {
+ // there are no more buffered items, so pruduce the next batch, if any
+
+ if (state->theIsDone)
+ return false;
+
+ iter->produceNext(planState);
+
+ if (state->theCurrItem == state->theEndItem)
+ {
+ // nothing was produced.
+ assert(state->theIsDone);
+ return false;
+ }
+ }
+
+ result.transfer(*state->theCurrItem);
+ ++state->theCurrItem;
+ return true;
}
@@ -502,74 +498,93 @@
~Batcher() {}
-
#if ZORBA_BATCHING_TYPE == 1
void produceNext(PlanState& planState) const
{
- PlanIteratorState* lState =
- StateTraitsImpl<PlanIteratorState>::getState(planState, stateOffset);
-#ifndef NDEBUG
- ZORBA_ASSERT(lState->theIsOpened);
-#endif
- bool more;
- uint32_t i = 0;
+ PlanIteratorState* state =
+ StateTraitsImpl<PlanIteratorState>::getState(planState, theStateOffset);
+ assert(state->theIsOpened);
+ state->theEndItem = &state->theBatch[ZORBA_BATCHING_BATCHSIZE];
+ state->theCurrItem = &state->theBatch[0];
do
{
// In general, to compute this iterator's next result, nextImpl() will
// call consumeNext() on one or more of this iterator's child iterators.
- more = static_cast<const IterType*>(this)->nextImpl(lState->theBatch[i], planState);
+ if (!static_cast<const IterType*>(this)->nextImpl(*state->theCurrItem, planState))
+ {
+ state->theEndItem = state->theCurrItem;
+ state->theCurrItem = &state->theBatch[0];
+ state->theIsDone = true;
+ return;
+ }
+
+ ++state->theCurrItem;
}
- while ( more && ++i < ZORBA_BATCHING_BATCHSIZE );
+ while (state->theCurrItem < state->theEndItem);
+
+ state->theCurrItem = &state->theBatch[0];
}
-#else
+#else // ZORBA_BATCHING_TYPE
bool produceNext(store::Item_t& result, PlanState& planState) const
{
#ifndef NDEBUG
- PlanIteratorState* lState =
+ PlanIteratorState* state =
StateTraitsImpl<PlanIteratorState>::getState(planState, theStateOffset);
- ZORBA_ASSERT(lState->theIsOpened);
+ ZORBA_ASSERT(state->theIsOpened);
#endif
return static_cast<const IterType*>(this)->nextImpl(result, planState);
}
#endif // ZORBA_BATCHING_TYPE
+#ifndef NDEBUG
void open(PlanState& planState, uint32_t& offset)
{
static_cast<IterType*>(this)->openImpl(planState, offset);
-#ifndef NDEBUG
// do this after openImpl because the state is created there
- PlanIteratorState* lState =
- StateTraitsImpl<PlanIteratorState>::getState(planState, theStateOffset);
- ZORBA_ASSERT( ! lState->theIsOpened ); // don't call open twice
- lState->theIsOpened = true;
-#endif
- }
-
- void reset(PlanState& planState) const
- {
-#ifndef NDEBUG
- PlanIteratorState* lState =
- StateTraitsImpl<PlanIteratorState>::getState(planState, theStateOffset);
- ZORBA_ASSERT( lState->theIsOpened );
-#endif
- static_cast<const IterType*>(this)->resetImpl(planState);
- }
-
- void close(PlanState& planState)
- {
-#ifndef NDEBUG
- PlanIteratorState* lState =
- StateTraitsImpl<PlanIteratorState>::getState(planState, theStateOffset);
- static_cast<IterType*>(this)->closeImpl(planState);
- lState->theIsOpened = false;
-#else
- static_cast<IterType*>(this)->closeImpl(planState);
-#endif
- }
+ PlanIteratorState* state =
+ StateTraitsImpl<PlanIteratorState>::getState(planState, theStateOffset);
+ ZORBA_ASSERT(!state->theIsOpened); // don't call open twice
+ state->theIsOpened = true;
+ }
+
+ void reset(PlanState& planState) const
+ {
+ PlanIteratorState* state =
+ StateTraitsImpl<PlanIteratorState>::getState(planState, theStateOffset);
+ ZORBA_ASSERT(state->theIsOpened);
+ static_cast<const IterType*>(this)->resetImpl(planState);
+ }
+
+ void close(PlanState& planState)
+ {
+ PlanIteratorState* state =
+ StateTraitsImpl<PlanIteratorState>::getState(planState, theStateOffset);
+ static_cast<IterType*>(this)->closeImpl(planState);
+ state->theIsOpened = false;
+ }
+
+#else // NDEBUG
+
+ void open(PlanState& planState, uint32_t& offset)
+ {
+ static_cast<IterType*>(this)->openImpl(planState, offset);
+ }
+
+ void reset(PlanState& planState) const
+ {
+ static_cast<const IterType*>(this)->resetImpl(planState);
+ }
+
+ void close(PlanState& planState)
+ {
+ static_cast<IterType*>(this)->closeImpl(planState);
+ }
+
+#endif // NDEBUG
inline bool nextImpl(store::Item_t& result, PlanState& planState) const;
=== modified file 'src/runtime/collections/collections_impl.cpp'
--- src/runtime/collections/collections_impl.cpp 2013-01-31 11:32:47 +0000
+++ src/runtime/collections/collections_impl.cpp 2013-02-15 00:39:22 +0000
@@ -132,206 +132,95 @@
bool FnCollectionIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
- store::Item_t lURI, resolvedURIItem;
store::Collection_t coll;
- std::auto_ptr<internal::Resource> lResource;
- internal::CollectionResource* lCollResource;
- zstring resolvedURIString;
zstring lErrorMessage;
- FnCollectionIteratorState *state;
+ FnCollectionIteratorState* state;
DEFAULT_STACK_INIT(FnCollectionIteratorState, state, planState);
- if (theChildren.size() == 1 &&
- consumeNext(lURI, theChildren[0].getp(), planState))
- {
- try
- {
- resolvedURIString = theSctx->resolve_relative_uri(lURI->getStringValue());
- }
- catch (ZorbaException const&)
- {
- RAISE_ERROR(err::FODC0004, loc,
- ERROR_PARAMS(lURI->getStringValue(), ZED(BadAnyURI)));
- }
- }
- else
- {
- resolvedURIItem = planState.theGlobalDynCtx->get_default_collection();
-
- if (NULL == resolvedURIItem)
- {
- RAISE_ERROR(err::FODC0002, loc,
- ERROR_PARAMS(ZED(DefaultCollation), ZED(NotDefInDynamicCtx)));
- }
-
- resolvedURIString = theSctx->resolve_relative_uri(resolvedURIItem->getStringValue());
- }
-
- lResource = theSctx->resolve_uri(resolvedURIString,
- internal::EntityData::COLLECTION,
- lErrorMessage);
-
- lCollResource = dynamic_cast<internal::CollectionResource*>(lResource.get());
-
- if ( lCollResource == 0 || !(coll = lCollResource->getCollection()) )
- {
- RAISE_ERROR(err::FODC0002, loc,
- ERROR_PARAMS(resolvedURIString, lErrorMessage));
- }
-
- /** return the nodes of the collection */
+ coll = getCollection(planState);
+
state->theIterator = coll->getIterator();
ZORBA_ASSERT(state->theIterator!=NULL);
state->theIterator->open();
state->theIteratorOpened = true;
while(state->theIterator->next(result))
+ {
STACK_PUSH (true, state);
+ }
// close as early as possible
state->theIterator->close();
state->theIteratorOpened = false;
- STACK_END (state);
-}
-
-
-/*******************************************************************************
- Iterator for optimizing fn:count when applied to collections
-********************************************************************************/
-CountCollectionIterator::CountCollectionIterator(
- static_context* sctx,
- const QueryLoc& loc,
- std::vector<PlanIter_t>& children,
- CollectionType collectionType)
- :
- NaryBaseIterator<CountCollectionIterator, PlanIteratorState>(sctx, loc, children),
- theCollectionType(collectionType)
-{
-}
-
-
-CountCollectionIterator::~CountCollectionIterator()
-{
-}
-
-
-void CountCollectionIterator::serialize(::zorba::serialization::Archiver& ar)
-{
- serialize_baseclass(ar,
- (NaryBaseIterator<CountCollectionIterator, PlanIteratorState>*)this);
-
- SERIALIZE_ENUM(enum CollectionType, theCollectionType);
-}
-
-
-bool CountCollectionIterator::nextImpl(store::Item_t& result, PlanState& planState) const
-{
- store::Collection_t coll;
- store::Item_t name;
- xs_integer lCount;
-
- PlanIteratorState* state;
- DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
-
- if (isZorbaCollection())
- {
- ZORBA_ASSERT(consumeNext(name, theChildren[0].getp(), planState));
-
- (void)getCollection(theSctx, name, loc, isDynamic(), coll);
- }
- else
- {
- coll = getW3CCollection(planState);
- }
-
- lCount = coll->size();
- if (theChildren.size() == 2)
- {
- // skip parameter passed
- store::Item_t lSkipItem;
- consumeNext(lSkipItem, theChildren[1].getp(), planState);
- xs_integer lSkip = lSkipItem->getIntegerValue();
- // negative is transformed into 0
- lCount -= ( lSkip <= xs_integer::zero() ? xs_integer::zero() : lSkip );
- // negative is transformed into 0
- lCount = ( lCount < xs_integer::zero() ? xs_integer::zero() : lCount );
- }
- else if(theChildren.size() > 2)
- {
- // if ref is passed to the collections function, count cannot be
- // optimized anymore. Hence this iterator must not be used.
- // In this case ZorbaCollectionIterator::isCountOptimizable() returns
- // false.
- assert(false);
- }
-
- STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, lCount), state);
-
STACK_END(state);
}
-store::Collection_t CountCollectionIterator::getW3CCollection(PlanState& planState) const
-{
- store::Item_t lURI;
+void FnCollectionIterator::count(store::Item_t& result, PlanState& planState) const
+{
+ store::Collection_t collection;
+ xs_integer count;
+
+ collection = getCollection(planState);
+
+ count = collection->size();
+
+ GENV_ITEMFACTORY->createInteger(result, count);
+}
+
+
+store::Collection_t FnCollectionIterator::getCollection(PlanState& planState) const
+{
+ store::Item_t uriItem;
store::Collection_t coll;
- std::auto_ptr<internal::Resource> lResource;
- internal::CollectionResource* lCollResource;
- zstring resolvedURIString;
- zstring lErrorMessage;
+ std::auto_ptr<internal::Resource> resource;
+ internal::CollectionResource* collResource;
+ zstring resolvedURI;
+ zstring errorMessage;
- if (!theChildren.empty()) //if a URI was given
+ if (!theChildren.empty() &&
+ consumeNext(uriItem, theChildren[0].getp(), planState))
{
- ZORBA_ASSERT(consumeNext(lURI, theChildren[0].getp(), planState));
-
try
{
- resolvedURIString = theSctx->resolve_relative_uri(lURI->getStringValue());
+ resolvedURI = theSctx->resolve_relative_uri(uriItem->getStringValue());
}
catch (ZorbaException const&)
{
RAISE_ERROR(err::FODC0004, loc,
- ERROR_PARAMS(lURI->getStringValue(), ZED(BadAnyURI)));
+ ERROR_PARAMS(uriItem->getStringValue(), ZED(BadAnyURI)));
}
}
else
{
- lURI = planState.theGlobalDynCtx->get_default_collection();
+ uriItem = planState.theGlobalDynCtx->get_default_collection();
- if( NULL == lURI)
+ if (NULL == uriItem)
{
RAISE_ERROR(err::FODC0002, loc,
ERROR_PARAMS(ZED(DefaultCollation), ZED(NotDefInDynamicCtx)));
}
- resolvedURIString = theSctx->resolve_relative_uri(lURI->getStringValue());
+ resolvedURI = theSctx->resolve_relative_uri(uriItem->getStringValue());
}
-
- lResource = theSctx->resolve_uri(resolvedURIString,
- internal::EntityData::COLLECTION,
- lErrorMessage);
-
- lCollResource = dynamic_cast<internal::CollectionResource*>(lResource.get());
-
- if (lCollResource == 0 || !(coll = lCollResource->getCollection()))
+ resource = theSctx->resolve_uri(resolvedURI,
+ internal::EntityData::COLLECTION,
+ errorMessage);
+
+ collResource = dynamic_cast<internal::CollectionResource*>(resource.get());
+
+ if (collResource == 0 || !(coll = collResource->getCollection()))
{
- RAISE_ERROR(err::FODC0004, loc,
- ERROR_PARAMS(resolvedURIString, lErrorMessage));
+ RAISE_ERROR(err::FODC0004, loc, ERROR_PARAMS(resolvedURI, errorMessage));
}
return coll;
}
-SERIALIZABLE_CLASS_VERSIONS(CountCollectionIterator)
-
-
-NARY_ACCEPT(CountCollectionIterator);
-
-
/*******************************************************************************
********************************************************************************/
@@ -449,12 +338,8 @@
}
catch ( std::range_error const& )
{
- throw XQUERY_EXCEPTION(
- zerr::ZXQD0004_INVALID_PARAMETER,
- ERROR_PARAMS(ZED(ZXQD0004_NOT_WITHIN_RANGE),
- lSkip),
- ERROR_LOC( loc )
- );
+ RAISE_ERROR(zerr::ZXQD0004_INVALID_PARAMETER, loc,
+ ERROR_PARAMS(ZED(ZXQD0004_NOT_WITHIN_RANGE), lSkip));
}
state->theIteratorOpened = true;
@@ -469,6 +354,38 @@
STACK_END(state);
}
+
+void ZorbaCollectionIterator::count(store::Item_t& result, PlanState& planState) const
+{
+ if (!isCountOptimizable())
+ return PlanIterator::count(result, planState);
+
+ store::Item_t name;
+ store::Collection_t collection;
+ xs_integer count;
+
+ consumeNext(name, theChildren[0].getp(), planState);
+
+ (void)getCollection(theSctx, name, loc, theIsDynamic, collection);
+
+ count = collection->size();
+
+ if (theChildren.size() == 2)
+ {
+ // skip parameter passed
+ store::Item_t skipItem;
+ consumeNext(skipItem, theChildren[1].getp(), planState);
+ xs_integer skip = skipItem->getIntegerValue();
+
+ count -= (skip <= xs_integer::zero() ? xs_integer::zero() : skip);
+
+ count = (count < xs_integer::zero() ? xs_integer::zero() : count);
+ }
+
+ GENV_ITEMFACTORY->createInteger(result, count);
+}
+
+
/*******************************************************************************
declare function index-of($name as xs:QName,
$target as node()) as xs:integer
=== modified file 'src/runtime/collections/collections_impl.h'
--- src/runtime/collections/collections_impl.h 2012-09-19 21:16:15 +0000
+++ src/runtime/collections/collections_impl.h 2013-02-15 00:39:22 +0000
@@ -24,58 +24,6 @@
namespace zorba{
-/*******************************************************************************
- Iterator to optimize a fn:count(collection) expression
-
- theCollectionType:
- ------------------
- Whether the Collection is a W3C or Zorba Collection and if it's dynamic or
- static collection module.
-********************************************************************************/
-class CountCollectionIterator : public NaryBaseIterator<CountCollectionIterator,
- PlanIteratorState>
-{
-public:
- enum CollectionType
- {
- W3C = 0,
- ZORBASTATIC = 1,
- ZORBADYNAMIC = 2
- };
-
-protected:
- CollectionType theCollectionType;
-
-public:
- SERIALIZABLE_CLASS(CountCollectionIterator);
-
- SERIALIZABLE_CLASS_CONSTRUCTOR2T(CountCollectionIterator,
- NaryBaseIterator<CountCollectionIterator, PlanIteratorState>);
-
- void serialize(::zorba::serialization::Archiver& ar);
-
-public:
- CountCollectionIterator(
- static_context* sctx,
- const QueryLoc& loc,
- std::vector<PlanIter_t>& children,
- CollectionType collectionType);
-
- ~CountCollectionIterator();
-
- bool isZorbaCollection() const { return W3C != theCollectionType; }
-
- bool isDynamic() const { return ZORBADYNAMIC == theCollectionType; }
-
- void accept(PlanIterVisitor& v) const;
-
- bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
-
-protected:
- store::Collection_t getZorbaCollection(PlanState& planState) const;
-
- store::Collection_t getW3CCollection(PlanState& planState) const;
-};
} //namespace zorba
#endif /* ZORBA_RUNTIME_COLLECTIONS_COLLECTIONS_IMPL_H */
=== modified file 'src/runtime/collections/pregenerated/collections.h'
--- src/runtime/collections/pregenerated/collections.h 2012-12-11 13:33:18 +0000
+++ src/runtime/collections/pregenerated/collections.h 2013-02-15 00:39:22 +0000
@@ -233,6 +233,9 @@
virtual ~FnCollectionIterator();
+public:
+ void count(store::Item_t& result, PlanState& planState) const;
+ store::Collection_t getCollection(PlanState& planState) const;
void accept(PlanIterVisitor& v) const;
bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
@@ -287,6 +290,7 @@
public:
bool isCountOptimizable() const;
+ void count(store::Item_t& result, PlanState& planState) const;
void accept(PlanIterVisitor& v) const;
bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
=== modified file 'src/runtime/core/path_iterators.cpp'
--- src/runtime/core/path_iterators.cpp 2012-10-12 21:07:51 +0000
+++ src/runtime/core/path_iterators.cpp 2013-02-15 00:39:22 +0000
@@ -1245,7 +1245,7 @@
{
if (!consumeNext(state->theContextNode, theChild.getp(), planState))
{
- state->reset(planState);
+ //state->reset(planState);
return false;
}
=== modified file 'src/runtime/sequences/sequences_impl.cpp'
--- src/runtime/sequences/sequences_impl.cpp 2013-01-11 10:18:14 +0000
+++ src/runtime/sequences/sequences_impl.cpp 2013-02-15 00:39:22 +0000
@@ -1205,27 +1205,35 @@
// //
/////////////////////////////////////////////////////////////////////////////////
+
/*******************************************************************************
15.4.1 fn:count
********************************************************************************/
bool FnCountIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
- store::Item_t lSequenceItem;
- ulong lCount = 0;
+ store::Item_t item;
+ ulong count = 0;
PlanIteratorState* state;
DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
- while (consumeNext(lSequenceItem, theChildren[0].getp(), planState))
+ theChildren[0]->count(result, planState);
+
+ STACK_PUSH(result, state);
+
+#if 0
+ while (consumeNext(item, theChildren[0].getp(), planState))
{
- ++lCount;
+ ++count;
}
- STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, Integer(lCount)), state);
+ STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, Integer(count)), state);
+#endif
STACK_END(state);
}
+
/*******************************************************************************
15.4.2 fn:avg
********************************************************************************/
=== modified file 'src/runtime/spec/collections/collections.xml'
--- src/runtime/spec/collections/collections.xml 2012-12-11 13:33:18 +0000
+++ src/runtime/spec/collections/collections.xml 2013-02-15 00:39:22 +0000
@@ -230,6 +230,15 @@
brief="flag indicating whether theIterator was opened"/>
</zorba:state>
+ <zorba:method name="count" const="true" return="void">
+ <zorba:param name="result" type="store::Item_t&"/>
+ <zorba:param name="planState" type="PlanState&"/>
+ </zorba:method>
+
+ <zorba:method name="getCollection" const="true" return="store::Collection_t">
+ <zorba:param name="planState" type="PlanState&"/>
+ </zorba:method>
+
</zorba:iterator>
<!--
@@ -298,10 +307,13 @@
<zorba:member type="bool" name="theIsDynamic" getterName="isDynamic"/>
- <zorba:method const="true"
- name="isCountOptimizable"
- return="bool" />
+ <zorba:method const="true" name="isCountOptimizable" return="bool" />
+ <zorba:method const="true" name="count" return="void">
+ <zorba:param name="result" type="store::Item_t&"/>
+ <zorba:param name="planState" type="PlanState&"/>
+ </zorba:method>
+
<zorba:state generateInit="false" generateReset="false" generateDestructor="false">
<zorba:member type="store::Iterator_t" name="theIterator"/>
<zorba:member type="bool" name="theIteratorOpened" defaultValue="false"/>
=== modified file 'src/runtime/spec/iterator_h.xq'
--- src/runtime/spec/iterator_h.xq 2012-09-19 21:16:15 +0000
+++ src/runtime/spec/iterator_h.xq 2013-02-15 00:39:22 +0000
@@ -251,38 +251,36 @@
declare function local:add-methods ($iter) as xs:string?
{
- fn:concat("public:", $gen:newline,
- fn:string-join(
+ fn:concat(
+ "public:",
+ $gen:newline,
+ fn:string-join
+ (
for $method in $iter/zorba:method
- return fn:concat(
- $gen:indent,
- if ($method/@static eq "true")
- then
- "static "
- else
- "",
- $method/@return,
- " ",
- $method/@name,
- "(",
- local:get-method-arguments($method),
- ")",
- if ($method/@const eq "true") then
- " const;"
- else ";"), $gen:newline),
- $gen:newline)
+ return fn:concat($gen:indent,
+ if ($method/@static eq "true") then "static " else "",
+ $method/@return,
+ " ",
+ $method/@name,
+ "(",
+ local:get-method-arguments($method),
+ ")",
+ if ($method/@const eq "true") then " const;" else ";"),
+ $gen:newline
+ ),
+ $gen:newline
+ )
};
declare function local:get-method-arguments($method) as xs:string?
{
- fn:string-join(
+ fn:string-join
+ (
for $param in $method/zorba:param
- return fn:concat(
- $param/@type,
- " ",
- $param/@name),
- ", ")
+ return fn:concat($param/@type, " ", $param/@name),
+ ", "
+ )
};
=== modified file 'src/runtime/visitors/planiter_visitor_impl_code.h'
--- src/runtime/visitors/planiter_visitor_impl_code.h 2013-01-11 22:58:12 +0000
+++ src/runtime/visitors/planiter_visitor_impl_code.h 2013-02-15 00:39:22 +0000
@@ -362,6 +362,4 @@
PLAN_ITER_VISITOR(ExitCatcherIterator);
PLAN_ITER_VISITOR(FlowCtlIterator);
-PLAN_ITER_VISITOR(CountCollectionIterator);
-
/* vim:set et sw=2 ts=2: */
=== modified file 'src/runtime/visitors/planiter_visitor_impl_include.h'
--- src/runtime/visitors/planiter_visitor_impl_include.h 2013-01-11 22:58:12 +0000
+++ src/runtime/visitors/planiter_visitor_impl_include.h 2013-02-15 00:39:22 +0000
@@ -184,8 +184,6 @@
class LoopIterator;
class FlowCtlIterator;
-class CountCollectionIterator;
-
#define PLAN_ITER_VISITOR(class) \
virtual void beginVisit ( const class& ) = 0; \
virtual void endVisit ( const class& ) = 0
=== modified file 'src/runtime/visitors/printer_visitor_impl.cpp'
--- src/runtime/visitors/printer_visitor_impl.cpp 2013-01-11 22:58:12 +0000
+++ src/runtime/visitors/printer_visitor_impl.cpp 2013-02-15 00:39:22 +0000
@@ -1522,7 +1522,5 @@
PRINTER_VISITOR_DEFINITION(ExitCatcherIterator);
PRINTER_VISITOR_DEFINITION(LoopIterator);
PRINTER_VISITOR_DEFINITION(FlowCtlIterator);
-
- PRINTER_VISITOR_DEFINITION(CountCollectionIterator);
}
/* vim:set et sw=2 ts=2: */
=== modified file 'src/runtime/visitors/printer_visitor_impl.h'
--- src/runtime/visitors/printer_visitor_impl.h 2013-01-11 22:58:12 +0000
+++ src/runtime/visitors/printer_visitor_impl.h 2013-02-15 00:39:22 +0000
@@ -317,6 +317,4 @@
DECLARE_VISITOR(LoopIterator);
DECLARE_VISITOR(FlowCtlIterator);
- DECLARE_VISITOR(CountCollectionIterator);
-
/* vim:set et sw=2 ts=2: */
=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/collections/count_dynamic_zorba_collection.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/collections/count_dynamic_zorba_collection.iter 2012-12-06 22:49:35 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/collections/count_dynamic_zorba_collection.iter 2013-02-15 00:39:22 +0000
@@ -9,9 +9,11 @@
<CtxVarIterator varid="4" varname="coll" varkind="global"/>
</ZorbaCreateCollectionIterator>
</ApplyIterator>
- <CountCollectionIterator>
- <CtxVarIterator varid="4" varname="coll" varkind="global"/>
- </CountCollectionIterator>
+ <FnCountIterator>
+ <ZorbaCollectionIterator>
+ <CtxVarIterator varid="4" varname="coll" varkind="global"/>
+ </ZorbaCollectionIterator>
+ </FnCountIterator>
</SequentialIterator>
</SequentialIterator>
=== modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/collections/count_static_zorba_collection.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/collections/count_static_zorba_collection.iter 2012-12-06 22:49:35 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/collections/count_static_zorba_collection.iter 2013-02-15 00:39:22 +0000
@@ -27,9 +27,11 @@
<CtxVarIterator varid="10" varname="coll" varkind="global"/>
</ZorbaCreateCollectionIterator>
</ApplyIterator>
- <CountCollectionIterator>
- <CtxVarIterator varid="10" varname="coll" varkind="global"/>
- </CountCollectionIterator>
+ <FnCountIterator>
+ <ZorbaCollectionIterator>
+ <CtxVarIterator varid="10" varname="coll" varkind="global"/>
+ </ZorbaCollectionIterator>
+ </FnCountIterator>
</SequentialIterator>
</SequentialIterator>
Follow ups
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: noreply, 2013-03-24
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Zorba Build Bot, 2013-03-24
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Zorba Build Bot, 2013-03-24
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Matthias Brantner, 2013-03-24
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Zorba Build Bot, 2013-03-24
-
Re: [Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Zorba Build Bot, 2013-03-24
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Matthias Brantner, 2013-03-24
-
Re: [Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Matthias Brantner, 2013-03-24
-
Re: [Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Markos Zaharioudakis, 2013-02-15
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Zorba Build Bot, 2013-02-15
-
Re: [Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Zorba Build Bot, 2013-02-15
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Zorba Build Bot, 2013-02-15
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Zorba Build Bot, 2013-02-15
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Markos Zaharioudakis, 2013-02-15
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Zorba Build Bot, 2013-02-15
-
Re: [Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Zorba Build Bot, 2013-02-15
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Zorba Build Bot, 2013-02-15
-
[Merge] lp:~zorba-coders/zorba/count-opt into lp:zorba
From: Markos Zaharioudakis, 2013-02-15