zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #13277
[Merge] lp:~davidagraf/zorba/paging_with_refs into lp:zorba
David Graf has proposed merging lp:~davidagraf/zorba/paging_with_refs into lp:zorba.
Requested reviews:
Till Westmann (tillw)
For more details, see:
https://code.launchpad.net/~davidagraf/zorba/paging_with_refs/+merge/119553
--
https://code.launchpad.net/~davidagraf/zorba/paging_with_refs/+merge/119553
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/functions/func_sequences_impl.cpp'
--- src/functions/func_sequences_impl.cpp 2012-08-14 11:13:50 +0000
+++ src/functions/func_sequences_impl.cpp 2012-08-14 14:29:21 +0000
@@ -543,16 +543,19 @@
ZorbaCollectionIterator& collection =
static_cast<ZorbaCollectionIterator&>(*argv[0]);
- return new CountCollectionIterator(
- sctx,
- loc,
- collection.getChildren(),
- (
- collection.isDynamic()
- ? CountCollectionIterator::ZORBADYNAMIC
- : CountCollectionIterator::ZORBASTATIC
- )
- );
+ if (collection.isCountOptimizable())
+ {
+ return new CountCollectionIterator(
+ sctx,
+ loc,
+ collection.getChildren(),
+ (
+ collection.isDynamic()
+ ? CountCollectionIterator::ZORBADYNAMIC
+ : CountCollectionIterator::ZORBASTATIC
+ )
+ );
+ }
}
else if (typeid(FnCollectionIterator) == counted_type)
{
=== modified file 'src/functions/pregenerated/func_collections.cpp'
--- src/functions/pregenerated/func_collections.cpp 2012-08-14 11:13:50 +0000
+++ src/functions/pregenerated/func_collections.cpp 2012-08-14 14:29:21 +0000
@@ -355,6 +355,20 @@
{
DECL_WITH_KIND(sctx, static_collections_dml_collection,
+ (createQName("http://www.zorba-xquery.com/modules/store/static/collections/dml","","collection"),
+ GENV_TYPESYSTEM.QNAME_TYPE_ONE,
+ GENV_TYPESYSTEM.INTEGER_TYPE_ONE,
+ GENV_TYPESYSTEM.ANY_URI_TYPE_ONE,
+ GENV_TYPESYSTEM.STRUCTURED_ITEM_TYPE_STAR),
+ FunctionConsts::STATIC_COLLECTIONS_DML_COLLECTION_3);
+
+ }
+
+
+
+
+ {
+ DECL_WITH_KIND(sctx, static_collections_dml_collection,
(createQName("http://www.zorba-xquery.com/modules/store/dynamic/collections/dml","","collection"),
GENV_TYPESYSTEM.QNAME_TYPE_ONE,
GENV_TYPESYSTEM.STRUCTURED_ITEM_TYPE_STAR),
@@ -379,6 +393,20 @@
{
+ DECL_WITH_KIND(sctx, static_collections_dml_collection,
+ (createQName("http://www.zorba-xquery.com/modules/store/dynamic/collections/dml","","collection"),
+ GENV_TYPESYSTEM.QNAME_TYPE_ONE,
+ GENV_TYPESYSTEM.INTEGER_TYPE_ONE,
+ GENV_TYPESYSTEM.ANY_URI_TYPE_ONE,
+ GENV_TYPESYSTEM.STRUCTURED_ITEM_TYPE_STAR),
+ FunctionConsts::DYNAMIC_COLLECTIONS_DML_COLLECTION_3);
+
+ }
+
+
+
+
+ {
DECL_WITH_KIND(sctx, static_collections_dml_collection_name,
(createQName("http://www.zorba-xquery.com/modules/store/static/collections/dml","","collection-name"),
GENV_TYPESYSTEM.STRUCTURED_ITEM_TYPE_ONE,
=== modified file 'src/functions/pregenerated/function_enum.h'
--- src/functions/pregenerated/function_enum.h 2012-08-14 11:13:50 +0000
+++ src/functions/pregenerated/function_enum.h 2012-08-14 14:29:21 +0000
@@ -55,8 +55,10 @@
FN_COLLECTION_1,
STATIC_COLLECTIONS_DML_COLLECTION_1,
STATIC_COLLECTIONS_DML_COLLECTION_2,
+ STATIC_COLLECTIONS_DML_COLLECTION_3,
DYNAMIC_COLLECTIONS_DML_COLLECTION_1,
DYNAMIC_COLLECTIONS_DML_COLLECTION_2,
+ DYNAMIC_COLLECTIONS_DML_COLLECTION_3,
STATIC_COLLECTIONS_DML_COLLECTION_NAME_1,
DYNAMIC_COLLECTIONS_DML_COLLECTION_NAME_1,
STATIC_COLLECTIONS_DML_INDEX_OF_1,
=== modified file 'src/runtime/collections/collections_impl.cpp'
--- src/runtime/collections/collections_impl.cpp 2012-08-14 11:13:50 +0000
+++ src/runtime/collections/collections_impl.cpp 2012-08-14 14:29:21 +0000
@@ -367,6 +367,12 @@
}
}
+bool ZorbaCollectionIterator::isCountOptimizable() const
+{
+ // if ref is passed to the collections function, count cannot be
+ // optimized anymore.
+ return theChildren.size() <= 2;
+}
bool ZorbaCollectionIterator::nextImpl(
store::Item_t& result,
@@ -375,6 +381,7 @@
store::Item_t name;
store::Collection_t collection;
xs_integer lSkip;
+ zstring lStartAfterRef;
ZorbaCollectionIteratorState* state;
DEFAULT_STACK_INIT(ZorbaCollectionIteratorState, state, planState);
@@ -389,17 +396,26 @@
store::Item_t lSkipItem;
consumeNext(lSkipItem, theChildren[1].getp(), planState);
lSkip = lSkipItem->getIntegerValue();
- // negative is transformed into 0
- state->theIterator = ( lSkip > xs_integer::zero()
- ? collection->getIterator(lSkip)
- : collection->getIterator()
- );
+ }
+
+ if (theChildren.size() == 1)
+ {
+ state->theIterator = collection->getIterator(lSkip);
}
else
{
state->theIterator = collection->getIterator();
}
+ if (theChildren.size() > 2)
+ {
+ // skip parameter passed
+ store::Item_t lRefItem;
+ consumeNext(lRefItem, theChildren[2].getp(), planState);
+ lStartAfterRef = lRefItem->getString();
+ state->theIterator = collection->getIterator(lSkip, lStartAfterRef);
+ }
+
ZORBA_ASSERT(state->theIterator != NULL);
try
=== modified file 'src/runtime/collections/pregenerated/collections.h'
--- src/runtime/collections/pregenerated/collections.h 2012-08-14 11:13:50 +0000
+++ src/runtime/collections/pregenerated/collections.h 2012-08-14 14:29:21 +0000
@@ -285,6 +285,8 @@
bool isDynamic() const { return theIsDynamic; }
+public:
+ bool isCountOptimizable() const;
void accept(PlanIterVisitor& v) const;
bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
=== modified file 'src/runtime/spec/collections/collections.xml'
--- src/runtime/spec/collections/collections.xml 2012-08-14 11:13:50 +0000
+++ src/runtime/spec/collections/collections.xml 2012-08-14 14:29:21 +0000
@@ -255,14 +255,30 @@
<zorba:output>structured-item()*</zorba:output>
</zorba:signature>
- <zorba:signature localname="collection" prefix="dynamic-collections-dml">
- <zorba:param>xs:QName</zorba:param>
- <zorba:output>structured-item()*</zorba:output>
- </zorba:signature>
-
- <zorba:signature localname="collection" prefix="dynamic-collections-dml">
- <zorba:param>xs:QName</zorba:param>
- <zorba:param>xs:integer</zorba:param><!-- nodes to skip -->
+ <zorba:signature localname="collection"
+ prefix="static-collections-dml">
+ <zorba:param>xs:QName</zorba:param>
+ <zorba:param>xs:integer</zorba:param><!-- nodes to skip -->
+ <zorba:param>xs:anyURI</zorba:param><!-- node ref after where to start -->
+ <zorba:output>structured-item()*</zorba:output>
+ </zorba:signature>
+
+ <zorba:signature localname="collection" prefix="dynamic-collections-dml">
+ <zorba:param>xs:QName</zorba:param>
+ <zorba:output>structured-item()*</zorba:output>
+ </zorba:signature>
+
+ <zorba:signature localname="collection" prefix="dynamic-collections-dml">
+ <zorba:param>xs:QName</zorba:param>
+ <zorba:param>xs:integer</zorba:param><!-- nodes to skip -->
+ <zorba:output>structured-item()*</zorba:output>
+ </zorba:signature>
+
+ <zorba:signature localname="collection"
+ prefix="dynamic-collections-dml">
+ <zorba:param>xs:QName</zorba:param>
+ <zorba:param>xs:integer</zorba:param><!-- nodes to skip -->
+ <zorba:param>xs:anyURI</zorba:param><!-- node ref after where to start -->
<zorba:output>structured-item()*</zorba:output>
</zorba:signature>
@@ -281,6 +297,10 @@
<zorba:member type="bool" name="theIsDynamic" getterName="isDynamic"/>
+ <zorba:method const="true"
+ name="isCountOptimizable"
+ return="bool" />
+
<zorba:state generateInit="false" generateReset="false" generateDestructor="false">
<zorba:member type="store::Iterator_t" name="theIterator"/>
<zorba:member type="bool" name="theIteratorOpened" defaultValue="false"/>
=== removed directory 'src/runtime/spec/json.moved'
=== modified file 'src/store/api/collection.h'
--- src/store/api/collection.h 2012-08-14 11:13:50 +0000
+++ src/store/api/collection.h 2012-08-14 14:29:21 +0000
@@ -54,11 +54,15 @@
* It is allowed to have several concurrent iterators on the same Collection,
* but each iterator should be used by a single thread only.
*
- * @param aSkip The number of collection entries to skip.
+ * @param aSkip The number of collection entries to skip.
+ * @param aStartAfterRef Iteration starts after noded identified by
+ * this reference. Behavior when reference is not
+ * found is store dependent.
* @return Iterator
*/
virtual Iterator_t getIterator(
- const xs_integer& aSkip = xs_integer::zero()) = 0;
+ const xs_integer& aSkip = xs_integer::zero(),
+ const zstring& aStartAfterRef = "") = 0;
/**
* Get the node at the given position in the collection.
=== modified file 'src/store/naive/collection.h'
--- src/store/naive/collection.h 2012-08-14 11:13:50 +0000
+++ src/store/naive/collection.h 2012-08-14 14:29:21 +0000
@@ -54,7 +54,9 @@
zorba::xs_integer size() const = 0;
- zorba::store::Iterator_t getIterator(const xs_integer& aSkip) = 0;
+ zorba::store::Iterator_t getIterator(
+ const xs_integer& aSkip,
+ const zstring& aStartAfterRef) = 0;
virtual zorba::store::Item_t nodeAt(xs_integer position) = 0;
=== modified file 'src/store/naive/simple_collection.cpp'
--- src/store/naive/simple_collection.cpp 2012-08-14 11:13:50 +0000
+++ src/store/naive/simple_collection.cpp 2012-08-14 14:29:21 +0000
@@ -81,9 +81,10 @@
Note: it is allowed to have several concurrent iterators on the same collection
but each iterator should be used by a single thread only.
********************************************************************************/
-store::Iterator_t SimpleCollection::getIterator(const xs_integer& aSkip)
+store::Iterator_t SimpleCollection::getIterator(const xs_integer& aSkip,
+ const zstring& aStartAfterRef)
{
- return new CollectionIter(this, aSkip);
+ return new CollectionIter(this, aSkip, aStartAfterRef);
}
@@ -609,15 +610,16 @@
********************************************************************************/
SimpleCollection::CollectionIter::CollectionIter(
SimpleCollection* collection,
- const xs_integer& aSkip)
+ const xs_integer& aSkip,
+ const zstring& aStartAfterRef)
:
theCollection(collection),
theHaveLock(false),
- theSkip(aSkip)
+ theSkip(aSkip),
+ theStartAfterRef(aStartAfterRef)
{
}
-
/*******************************************************************************
********************************************************************************/
@@ -627,6 +629,41 @@
theCollection->theLatch.unlock();)
}
+void SimpleCollection::CollectionIter::skip()
+{
+ // Start Iteration after reference
+ // dummy implementation for main memory store
+ if (theStartAfterRef.size() > 0)
+ {
+ while (theIterator != theEnd)
+ {
+ store::Item_t lCur = *theIterator;
+ if (lCur->getKind() == zorba::store::Item::NODE)
+ {
+ const XmlNode*
+ xmlNode = static_cast<const XmlNode*>(lCur.getp());
+ if (xmlNode->haveReference())
+ {
+ zstring lReference;
+ GET_STORE().getNodeReference(lReference, lCur.getp());
+ if (theStartAfterRef == lReference)
+ {
+ ++ theIterator;
+ break;
+ }
+ }
+ }
+ ++theIterator;
+ }
+ }
+
+ // skip by position
+ for (long i = 0; i < to_xs_long(theSkip) && theIterator != theEnd; ++i)
+ {
+ ++theIterator;
+ }
+}
+
/*******************************************************************************
@@ -637,8 +674,8 @@
theHaveLock = true;
theIterator = theCollection->theXmlTrees.begin();
- theIterator += to_xs_long(theSkip);
theEnd = theCollection->theXmlTrees.end();
+ skip();
}
@@ -672,8 +709,8 @@
void SimpleCollection::CollectionIter::reset()
{
theIterator = theCollection->theXmlTrees.begin();
- theIterator += to_xs_long(theSkip);
theEnd = theCollection->theXmlTrees.end();
+ skip();
}
=== modified file 'src/store/naive/simple_collection.h'
--- src/store/naive/simple_collection.h 2012-08-14 11:13:50 +0000
+++ src/store/naive/simple_collection.h 2012-08-14 14:29:21 +0000
@@ -55,9 +55,12 @@
checked_vector<store::Item_t>::iterator theEnd;
bool theHaveLock;
xs_integer theSkip;
+ zstring theStartAfterRef;
public:
- CollectionIter(SimpleCollection* collection, const xs_integer& aSkip);
+ CollectionIter(SimpleCollection* collection,
+ const xs_integer& aSkip,
+ const zstring& aStartAfterRef);
~CollectionIter();
@@ -65,6 +68,8 @@
bool next(store::Item_t& result);
void reset();
void close();
+ private:
+ void skip();
};
@@ -110,7 +115,10 @@
TreeId createTreeId();
- store::Iterator_t getIterator(const xs_integer& aSkip);
+ store::Iterator_t getIterator(const xs_integer& aSkip,
+ const zstring& aStartAfterRef);
+
+ store::Iterator_t getIterator(const zstring& aRefBoundary);
void addNode(store::Item* node, xs_integer position = xs_integer(-1));
=== modified file 'src/store/naive/simple_store.cpp'
--- src/store/naive/simple_store.cpp 2012-08-14 11:13:50 +0000
+++ src/store/naive/simple_store.cpp 2012-08-14 14:29:21 +0000
@@ -276,6 +276,21 @@
********************************************************************************/
bool SimpleStore::getNodeReference(store::Item_t& result, const store::Item* node)
{
+ zstring lStrResult;
+
+ getNodeReference(lStrResult, node);
+
+ return theItemFactory->createAnyURI(result, lStrResult);
+}
+
+/*******************************************************************************
+ Computes the reference of the given node.
+
+ @param node XDM node
+ @return the identifier as a zstring
+********************************************************************************/
+void SimpleStore::getNodeReference(zstring& result, const store::Item* node)
+{
const XmlNode* xmlNode = static_cast<const XmlNode*>(node);
if (xmlNode->haveReference())
@@ -284,17 +299,15 @@
ZORBA_FATAL(resIt != theNodeToReferencesMap.end(),"Node reference cannot be found");
- zstring id = (*resIt).second;
- return theItemFactory->createAnyURI(result, id);
+ result = (*resIt).second;
+ return;
}
uuid_t uuid;
uuid_create(&uuid);
- zstring uuidStr = uuidToURI(uuid);
-
- assignReference(xmlNode, uuidStr);
-
- return theItemFactory->createAnyURI(result, uuidStr);
+ result = uuidToURI(uuid);
+
+ assignReference(xmlNode, result);
}
=== modified file 'src/store/naive/simple_store.h'
--- src/store/naive/simple_store.h 2012-08-14 11:13:50 +0000
+++ src/store/naive/simple_store.h 2012-08-14 14:29:21 +0000
@@ -108,6 +108,8 @@
bool getNodeReference(store::Item_t& result, const store::Item* node);
+ void getNodeReference(zstring& result, const store::Item* node);
+
bool hasReference(const store::Item* node);
bool assignReference(const store::Item* node, const zstring& reference);
=== modified file 'src/store/naive/store.h'
--- src/store/naive/store.h 2012-08-14 11:13:50 +0000
+++ src/store/naive/store.h 2012-08-14 14:29:21 +0000
@@ -414,6 +414,8 @@
public:
virtual bool getNodeReference(store::Item_t& result, const store::Item* node) = 0;
+ virtual void getNodeReference(zstring& result, const store::Item* node) = 0;
+
virtual bool hasReference(const store::Item* node) = 0;
virtual bool getNodeByReference(store::Item_t& result, const zstring& ref) = 0;
=== modified file 'test/rbkt/ExpQueryResults/zorba/collections/paging_1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/collections/paging_1.xml.res 2012-06-28 18:19:34 +0000
+++ test/rbkt/ExpQueryResults/zorba/collections/paging_1.xml.res 2012-08-14 14:29:21 +0000
@@ -1,1 +1,1 @@
-<d/><e/><a/><b/><c/><d/><e/>
+<d/><e/><delim/><a/><b/><c/><d/><e/><delim/><d/><e/>
=== modified file 'test/rbkt/ExpQueryResults/zorba/collections/paging_2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/collections/paging_2.xml.res 2012-06-28 18:19:34 +0000
+++ test/rbkt/ExpQueryResults/zorba/collections/paging_2.xml.res 2012-08-14 14:29:21 +0000
@@ -1,1 +1,1 @@
-2 5 0
+2 5 0 2
=== modified file 'test/rbkt/ExpQueryResults/zorba/collections/paging_3.xml.res'
--- test/rbkt/ExpQueryResults/zorba/collections/paging_3.xml.res 2012-06-28 18:19:34 +0000
+++ test/rbkt/ExpQueryResults/zorba/collections/paging_3.xml.res 2012-08-14 14:29:21 +0000
@@ -1,1 +1,1 @@
-<d/><e/><a/><b/><c/><d/><e/>
+<d/><e/><delim/><a/><b/><c/><d/><e/><delim/><d/><e/>
=== modified file 'test/rbkt/ExpQueryResults/zorba/collections/paging_4.xml.res'
--- test/rbkt/ExpQueryResults/zorba/collections/paging_4.xml.res 2012-06-28 18:19:34 +0000
+++ test/rbkt/ExpQueryResults/zorba/collections/paging_4.xml.res 2012-08-14 14:29:21 +0000
@@ -1,1 +1,1 @@
-2 5 0
+2 5 0 2
=== modified file 'test/rbkt/Queries/zorba/collections/paging_1.xq'
--- test/rbkt/Queries/zorba/collections/paging_1.xq 2012-06-28 18:19:34 +0000
+++ test/rbkt/Queries/zorba/collections/paging_1.xq 2012-08-14 14:29:21 +0000
@@ -1,6 +1,7 @@
import module namespace ddl = "http://www.zorba-xquery.com/modules/store/static/collections/ddl";
import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml";
import module namespace ns = "http://example.org/datamodule/" at "collections.xqdata";
+import module namespace ref = "http://www.zorba-xquery.com/modules/node-reference";
declare namespace ann = "http://www.zorba-xquery.com/annotations";
@@ -11,8 +12,10 @@
dml:insert-nodes(xs:QName("ns:test2"), <b/>);
dml:insert-nodes(xs:QName("ns:test2"), (<c/>, <d/>, <e/>));
(
- dml:collection(xs:QName("ns:test2"), 3),
- dml:collection(xs:QName("ns:test2"), -1)
+ dml:collection(xs:QName("ns:test2"), 3), <delim/>,
+ dml:collection(xs:QName("ns:test2"), -1), <delim/>,
+ let $ref := ref:node-reference(dml:collection(xs:QName("ns:test2"))[3])
+ return dml:collection(xs:QName("ns:test2"), 0, $ref)
)
};
=== modified file 'test/rbkt/Queries/zorba/collections/paging_2.xq'
--- test/rbkt/Queries/zorba/collections/paging_2.xq 2012-06-28 18:19:34 +0000
+++ test/rbkt/Queries/zorba/collections/paging_2.xq 2012-08-14 14:29:21 +0000
@@ -1,6 +1,7 @@
import module namespace ddl = "http://www.zorba-xquery.com/modules/store/static/collections/ddl";
import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml";
import module namespace ns = "http://example.org/datamodule/" at "collections.xqdata";
+import module namespace ref = "http://www.zorba-xquery.com/modules/node-reference";
declare namespace ann = "http://www.zorba-xquery.com/annotations";
@@ -13,7 +14,9 @@
(
fn:count(dml:collection(xs:QName("ns:test2"), 3)),
fn:count(dml:collection(xs:QName("ns:test2"), -1)),
- fn:count(dml:collection(xs:QName("ns:test2"), 100))
+ fn:count(dml:collection(xs:QName("ns:test2"), 100)),
+ let $ref := ref:node-reference(dml:collection(xs:QName("ns:test2"))[3])
+ return fn:count(dml:collection(xs:QName("ns:test2"), 0, $ref))
)
};
=== modified file 'test/rbkt/Queries/zorba/collections/paging_3.xq'
--- test/rbkt/Queries/zorba/collections/paging_3.xq 2012-06-28 18:19:34 +0000
+++ test/rbkt/Queries/zorba/collections/paging_3.xq 2012-08-14 14:29:21 +0000
@@ -1,5 +1,6 @@
import module namespace ddl = "http://www.zorba-xquery.com/modules/store/dynamic/collections/ddl";
import module namespace dml = "http://www.zorba-xquery.com/modules/store/dynamic/collections/dml";
+import module namespace ref = "http://www.zorba-xquery.com/modules/node-reference";
declare namespace ann = "http://www.zorba-xquery.com/annotations";
declare namespace ns = "http://www.zorba-xquery.com/test";
@@ -11,8 +12,10 @@
dml:insert-nodes-last(xs:QName("ns:test2"), <b/>);
dml:insert-nodes-last(xs:QName("ns:test2"), (<c/>, <d/>, <e/>));
(
- dml:collection(xs:QName("ns:test2"), 3),
- dml:collection(xs:QName("ns:test2"), -1)
+ dml:collection(xs:QName("ns:test2"), 3), <delim/>,
+ dml:collection(xs:QName("ns:test2"), -1), <delim/>,
+ let $ref := ref:node-reference(dml:collection(xs:QName("ns:test2"))[3])
+ return dml:collection(xs:QName("ns:test2"), 0, $ref)
)
};
=== modified file 'test/rbkt/Queries/zorba/collections/paging_4.xq'
--- test/rbkt/Queries/zorba/collections/paging_4.xq 2012-06-28 18:19:34 +0000
+++ test/rbkt/Queries/zorba/collections/paging_4.xq 2012-08-14 14:29:21 +0000
@@ -1,5 +1,6 @@
import module namespace ddl = "http://www.zorba-xquery.com/modules/store/dynamic/collections/ddl";
import module namespace dml = "http://www.zorba-xquery.com/modules/store/dynamic/collections/dml";
+import module namespace ref = "http://www.zorba-xquery.com/modules/node-reference";
declare namespace ann = "http://www.zorba-xquery.com/annotations";
declare namespace ns = "http://www.zorba-xquery.com/test";
@@ -13,7 +14,9 @@
(
fn:count(dml:collection(xs:QName("ns:test2"), 3)),
fn:count(dml:collection(xs:QName("ns:test2"), -1)),
- fn:count(dml:collection(xs:QName("ns:test2"), 100))
+ fn:count(dml:collection(xs:QName("ns:test2"), 100)),
+ let $ref := ref:node-reference(dml:collection(xs:QName("ns:test2"))[3])
+ return fn:count(dml:collection(xs:QName("ns:test2"), 0, $ref))
)
};
Follow ups