Merge lp:~zorba-coders/zorba/markos-scratch into lp:zorba
- markos-scratch
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Markos Zaharioudakis |
Approved revision: | 11149 |
Merged at revision: | 11516 |
Proposed branch: | lp:~zorba-coders/zorba/markos-scratch |
Merge into: | lp:zorba |
Diff against target: |
725 lines (+334/-143) 10 files modified
ChangeLog (+2/-0) src/functions/udf.cpp (+7/-26) src/runtime/core/fncall_iterator.cpp (+172/-102) src/runtime/core/fncall_iterator.h (+17/-10) src/runtime/util/item_iterator.cpp (+1/-1) src/runtime/util/item_iterator.h (+6/-4) src/runtime/util/single_item_iterator.h (+80/-0) test/rbkt/ExpQueryResults/zorba/udf/cache01.xml.res (+6/-0) test/rbkt/ExpQueryResults/zorba/udf/cache_01.xml.res (+6/-0) test/rbkt/Queries/zorba/udf/cache_01.xq (+37/-0) |
To merge this branch: | bzr merge lp:~zorba-coders/zorba/markos-scratch |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Markos Zaharioudakis | Approve | ||
Review via email: mp+169606@code.launchpad.net |
Commit message
Optimized implementation of function caching and removed the restriction on the return type.
Description of the change
Optimized implementation of function caching and removed the restriction on the return type.
Markos Zaharioudakis (markos-za) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/markos-scratch into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job markos-
The final status was:
No tests were run - build or configure step must have failed.
Not commiting changes.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/markos-scratch into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job markos-
The final status was:
No tests were run - build or configure step must have failed.
Not commiting changes.
Error in read script: /home/ceej/
- 11149. By Markos Zaharioudakis
-
added missing file
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job markos-
All tests succeeded!
Preview Diff
1 | === modified file 'ChangeLog' |
2 | --- ChangeLog 2013-06-14 05:20:13 +0000 |
3 | +++ ChangeLog 2013-06-16 06:47:28 +0000 |
4 | @@ -16,6 +16,8 @@ |
5 | if the FOR clause is followed by an orderby or groupby clause. |
6 | * Replaced use of create_value_type() in runtime with getTypeCode(). |
7 | * Optimized switch expression |
8 | + * Optimized implementation of function caching and removed the restriction |
9 | + on the return type. |
10 | |
11 | Bug Fixes/Other Changes: |
12 | * Fixed bug #1117952 (Improve XML error output format) |
13 | |
14 | === modified file 'src/functions/udf.cpp' |
15 | --- src/functions/udf.cpp 2013-05-08 20:14:47 +0000 |
16 | +++ src/functions/udf.cpp 2013-06-16 06:47:28 +0000 |
17 | @@ -651,14 +651,14 @@ |
18 | } |
19 | |
20 | // was the %ann:cache annotation given explicitly by the user |
21 | - bool lExplicitCacheRequest = |
22 | + bool explicitCacheRequest = |
23 | (theAnnotationList ? |
24 | theAnnotationList->contains(AnnotationInternal::zann_cache) : |
25 | false); |
26 | |
27 | if (isVariadic()) |
28 | { |
29 | - if (lExplicitCacheRequest) |
30 | + if (explicitCacheRequest) |
31 | { |
32 | diag->add_warning( |
33 | NEW_XQUERY_WARNING(zwarn::ZWST0005_CACHING_NOT_POSSIBLE, |
34 | @@ -668,27 +668,9 @@ |
35 | return; |
36 | } |
37 | |
38 | - // parameter and return types are subtype of xs:anyAtomicType? |
39 | - const xqtref_t& lRes = theSignature.returnType(); |
40 | TypeManager* tm = theBodyExpr->get_sctx()->get_typemanager(); |
41 | |
42 | - if (!TypeOps::is_subtype(tm, |
43 | - *lRes, |
44 | - *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_ONE, |
45 | - theLoc)) |
46 | - { |
47 | - if (lExplicitCacheRequest) |
48 | - { |
49 | - diag->add_warning( |
50 | - NEW_XQUERY_WARNING(zwarn::ZWST0005_CACHING_NOT_POSSIBLE, |
51 | - WARN_PARAMS(getName()->getStringValue(), |
52 | - ZED(ZWST0005_RETURN_TYPE), |
53 | - lRes->toString()), |
54 | - WARN_LOC(theLoc))); |
55 | - } |
56 | - return; |
57 | - } |
58 | - |
59 | + // parameter and return types are subtype of xs:anyAtomicType |
60 | csize lArity = theSignature.paramCount(); |
61 | for (csize i = 0; i < lArity; ++i) |
62 | { |
63 | @@ -698,7 +680,7 @@ |
64 | *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_ONE, |
65 | theLoc)) |
66 | { |
67 | - if (lExplicitCacheRequest) |
68 | + if (explicitCacheRequest) |
69 | { |
70 | diag->add_warning( |
71 | NEW_XQUERY_WARNING(zwarn::ZWST0005_CACHING_NOT_POSSIBLE, |
72 | @@ -715,7 +697,7 @@ |
73 | // function updating? |
74 | if (isUpdating()) |
75 | { |
76 | - if (lExplicitCacheRequest) |
77 | + if (explicitCacheRequest) |
78 | { |
79 | diag->add_warning( |
80 | NEW_XQUERY_WARNING(zwarn::ZWST0005_CACHING_NOT_POSSIBLE, |
81 | @@ -727,7 +709,7 @@ |
82 | |
83 | if (isSequential() || !isDeterministic()) |
84 | { |
85 | - if (lExplicitCacheRequest) |
86 | + if (explicitCacheRequest) |
87 | { |
88 | diag->add_warning( |
89 | NEW_XQUERY_WARNING(zwarn::ZWST0006_CACHING_MIGHT_NOT_BE_INTENDED, |
90 | @@ -740,9 +722,8 @@ |
91 | return; |
92 | } |
93 | |
94 | - |
95 | // optimization is prerequisite before invoking isRecursive |
96 | - if (!lExplicitCacheRequest && isOptimized() && !isRecursive()) |
97 | + if (!explicitCacheRequest && isOptimized() && !isRecursive()) |
98 | { |
99 | return; |
100 | } |
101 | |
102 | === modified file 'src/runtime/core/fncall_iterator.cpp' |
103 | --- src/runtime/core/fncall_iterator.cpp 2013-04-24 01:35:58 +0000 |
104 | +++ src/runtime/core/fncall_iterator.cpp 2013-06-16 06:47:28 +0000 |
105 | @@ -55,6 +55,7 @@ |
106 | |
107 | |
108 | #ifdef ZORBA_WITH_DEBUGGER |
109 | + |
110 | #include "debugger/debugger_commons.h" |
111 | |
112 | #define DEBUGGER_COMMONS state->thePlanState->theDebuggerCommons |
113 | @@ -78,6 +79,12 @@ |
114 | if (DEBUGGER_COMMONS) { \ |
115 | DEBUGGER_COMMONS->popStackFrame(); \ |
116 | } |
117 | + |
118 | +#else |
119 | + |
120 | +#define DEBUGGER_PUSH_FRAME |
121 | +#define DEBUGGER_POP_FRAME |
122 | + |
123 | #endif |
124 | |
125 | namespace zorba { |
126 | @@ -179,8 +186,6 @@ |
127 | { |
128 | thePlan->reset(*thePlanState); |
129 | } |
130 | - |
131 | - theArgValues.clear(); |
132 | } |
133 | |
134 | |
135 | @@ -244,34 +249,45 @@ |
136 | PlanState& planState, |
137 | UDFunctionCallIteratorState* state) |
138 | { |
139 | - store::Index_t lIndex = theUDF->getCache(); |
140 | - |
141 | - if (!lIndex && theUDF->cacheResults()) |
142 | + if (theUDF->cacheResults()) |
143 | { |
144 | - const signature& sig = theUDF->getSignature(); |
145 | + store::Index_t index = theUDF->getCache(); |
146 | |
147 | csize numArgs = theChildren.size(); |
148 | |
149 | - store::IndexSpecification lSpec; |
150 | - lSpec.theNumKeyColumns = numArgs; |
151 | - lSpec.theKeyTypes.resize(numArgs); |
152 | - lSpec.theCollations.resize(numArgs); |
153 | - lSpec.theIsTemp = true; |
154 | - lSpec.theIsUnique = true; |
155 | + if (!index) |
156 | + { |
157 | + const signature& sig = theUDF->getSignature(); |
158 | + |
159 | + store::IndexSpecification lSpec; |
160 | + lSpec.theNumKeyColumns = numArgs; |
161 | + lSpec.theKeyTypes.resize(numArgs); |
162 | + lSpec.theCollations.resize(numArgs); |
163 | + lSpec.theIsTemp = true; |
164 | + lSpec.theIsUnique = false; |
165 | + |
166 | + for (csize i = 0; i < numArgs; ++i) |
167 | + { |
168 | + lSpec.theKeyTypes[i] = sig[i]->getBaseBuiltinType()->getQName().getp(); |
169 | + } |
170 | + |
171 | + index = GENV_STORE.createIndex(theUDF->getName(), lSpec, 0); |
172 | + |
173 | + theUDF->setCache(index.getp()); // cache the cache in the function itself |
174 | + |
175 | + state->theArgValues.reserve(numArgs); |
176 | + } |
177 | + |
178 | + state->theCache = index.getp(); |
179 | + state->theCacheCond = index->createCondition(store::IndexCondition::POINT_VALUE); |
180 | + state->theCacheProbeIte = GENV_ITERATOR_FACTORY->createIndexProbeIterator(index); |
181 | + state->theArgValues.resize(numArgs); |
182 | |
183 | for (csize i = 0; i < numArgs; ++i) |
184 | { |
185 | - lSpec.theKeyTypes[i] = sig[i]->getBaseBuiltinType()->getQName().getp(); |
186 | + state->theArgValues[i] = new SingleItemIterator(); |
187 | } |
188 | - |
189 | - lIndex = GENV_STORE.createIndex(theUDF->getName(), lSpec, 0); |
190 | - |
191 | - theUDF->setCache(lIndex.getp()); // cache the cache in the function itself |
192 | - |
193 | - state->theArgValues.reserve(numArgs); |
194 | } |
195 | - |
196 | - state->theCache = lIndex.getp(); |
197 | } |
198 | |
199 | |
200 | @@ -284,11 +300,9 @@ |
201 | store::Item_t& result, |
202 | std::vector<store::Item_t>& argValues) const |
203 | { |
204 | - if (!state->theCache) |
205 | - return false; |
206 | + assert(state->theCache); |
207 | |
208 | - store::IndexCondition_t cond = |
209 | - state->theCache->createCondition(store::IndexCondition::POINT_VALUE); |
210 | + state->theCacheCond->clear(); |
211 | |
212 | std::vector<store::Iterator_t>::iterator ite = state->theArgWrappers.begin(); |
213 | |
214 | @@ -296,21 +310,21 @@ |
215 | { |
216 | store::Iterator_t& argWrapper = (*ite); |
217 | store::Item_t argValue; |
218 | + |
219 | if (argWrapper) // might be 0 if argument is not used |
220 | { |
221 | argWrapper->next(argValue); // guaranteed to have exactly one result |
222 | } |
223 | + |
224 | argValues.push_back(argValue); |
225 | - cond->pushItem(argValue); |
226 | + |
227 | + state->theCacheCond->pushItem(argValue); |
228 | } |
229 | |
230 | - store::IndexProbeIterator_t probeIte = |
231 | - GENV_STORE.getIteratorFactory()->createIndexProbeIterator(state->theCache); |
232 | - |
233 | - probeIte->init(cond); |
234 | - probeIte->open(); |
235 | - |
236 | - return probeIte->next(result); |
237 | + state->theCacheProbeIte->init(state->theCacheCond); |
238 | + state->theCacheProbeIte->open(); |
239 | + |
240 | + return state->theCacheProbeIte->next(result); |
241 | } |
242 | |
243 | |
244 | @@ -320,18 +334,22 @@ |
245 | void UDFunctionCallIterator::insertCacheEntry( |
246 | UDFunctionCallIteratorState* state, |
247 | std::vector<store::Item_t>& argValues, |
248 | - store::Item_t& udfValue) const |
249 | + const store::Item_t& udfResult) const |
250 | { |
251 | - if (state->theCache) |
252 | - { |
253 | - std::auto_ptr<store::IndexKey> k(new store::IndexKey()); |
254 | - store::IndexKey* k2 = k.get(); |
255 | - k->theItems = argValues; |
256 | - store::Item_t lTmp = udfValue; // insert will eventually transfer the Item_t |
257 | - if (!state->theCache->insert(k2, lTmp)) |
258 | - { |
259 | - k.release(); |
260 | - } |
261 | + assert(state->theCache); |
262 | + |
263 | + state->theCacheKey = new store::IndexKey(); |
264 | + state->theCacheKey->theItems.swap(argValues); |
265 | + store::Item_t tmp = udfResult; |
266 | + |
267 | + try |
268 | + { |
269 | + ZORBA_ASSERT(!state->theCache->insert(state->theCacheKey, tmp)); |
270 | + } |
271 | + catch (...) |
272 | + { |
273 | + delete state->theCacheKey; |
274 | + throw; |
275 | } |
276 | } |
277 | |
278 | @@ -449,8 +467,9 @@ |
279 | { |
280 | try |
281 | { |
282 | - std::vector<store::Item_t> lKey; |
283 | - bool lCacheHit; |
284 | + std::vector<store::Item_t> argValues; |
285 | + bool cacheHit; |
286 | + store::Item_t tmp; |
287 | |
288 | UDFunctionCallIteratorState* state; |
289 | DEFAULT_STACK_INIT(UDFunctionCallIteratorState, state, planState); |
290 | @@ -465,82 +484,133 @@ |
291 | state->thePlanOpen = true; |
292 | } |
293 | |
294 | - // check if there is a cache and the result is already in the cache |
295 | - lCacheHit = probeCache(planState, state, result, lKey); |
296 | - |
297 | - // if not in the cache, we bind the arguments to the function |
298 | - if (!lCacheHit) |
299 | - { |
300 | - const std::vector<ArgVarRefs>& argsRefs = theUDF->getArgVarsRefs(); |
301 | - const std::vector<store::Iterator_t>& argWraps = state->theArgWrappers; |
302 | - |
303 | - for (size_t i = 0; i < argsRefs.size(); ++i) |
304 | - { |
305 | - if (argWraps[i] != NULL) |
306 | - { |
307 | - const ArgVarRefs& argVarRefs = argsRefs[i]; |
308 | - store::Iterator_t argWrapper; |
309 | - if (state->theCache) |
310 | - { |
311 | - std::vector<store::Item_t> lParam(1, lKey[i]); |
312 | - state->theArgValues.push_back(GENV_STORE.createTempSeq(lParam)); |
313 | - argWrapper = state->theArgValues.back()->getIterator(); |
314 | - argWrapper->open(); |
315 | - } |
316 | - else |
317 | - { |
318 | + if (state->theCache) |
319 | + { |
320 | + // check if the result is already in the cache |
321 | + cacheHit = probeCache(planState, state, result, argValues); |
322 | + |
323 | + // if not in the cache, we bind the arguments to the function |
324 | + if (!cacheHit) |
325 | + { |
326 | + const std::vector<ArgVarRefs>& argsRefs = theUDF->getArgVarsRefs(); |
327 | + const std::vector<store::Iterator_t>& argWraps = state->theArgWrappers; |
328 | + |
329 | + for (csize i = 0; i < argsRefs.size(); ++i) |
330 | + { |
331 | + if (argWraps[i] != NULL) |
332 | + { |
333 | + const ArgVarRefs& argVarRefs = argsRefs[i]; |
334 | + store::Iterator_t argWrapper; |
335 | + |
336 | + store::Item_t argValue = argValues[i]; |
337 | + state->theArgValues[i]->init(argValue); |
338 | + argWrapper = state->theArgValues[i]; |
339 | + |
340 | + ArgVarRefs::const_iterator argVarRefsIte = argVarRefs.begin(); |
341 | + ArgVarRefs::const_iterator argVarRefsEnd = argVarRefs.end(); |
342 | + |
343 | + for (; argVarRefsIte != argVarRefsEnd; ++argVarRefsIte) |
344 | + { |
345 | + const LetVarIter_t& argRef = (*argVarRefsIte); |
346 | + assert(argRef != NULL); |
347 | + |
348 | + if (argRef != NULL) |
349 | + { |
350 | + argRef->bind(argWrapper, *state->thePlanState); |
351 | + } |
352 | + } |
353 | + } |
354 | + } |
355 | + } |
356 | + |
357 | + if (!cacheHit) |
358 | + { |
359 | + DEBUGGER_PUSH_FRAME; |
360 | + |
361 | + if (consumeNext(result, state->thePlan, *state->thePlanState)) |
362 | + { |
363 | + insertCacheEntry(state, argValues, result); |
364 | + |
365 | + DEBUGGER_POP_FRAME; |
366 | + STACK_PUSH(true, state); |
367 | + DEBUGGER_PUSH_FRAME; |
368 | + |
369 | + while (consumeNext(result, state->thePlan, *state->thePlanState)) |
370 | + { |
371 | + tmp = result; |
372 | + ZORBA_ASSERT(state->theCache->insert(state->theCacheKey, tmp)); |
373 | + |
374 | + DEBUGGER_POP_FRAME; |
375 | + STACK_PUSH(true, state); |
376 | + DEBUGGER_PUSH_FRAME; |
377 | + } |
378 | + } |
379 | + else |
380 | + { |
381 | + insertCacheEntry(state, argValues, NULL); |
382 | + } |
383 | + |
384 | + DEBUGGER_POP_FRAME; |
385 | + } |
386 | + else // cache hit |
387 | + { |
388 | + if (result != NULL) |
389 | + { |
390 | + STACK_PUSH(true, state); |
391 | + |
392 | + while (state->theCacheProbeIte->next(result)) |
393 | + { |
394 | + STACK_PUSH(true, state); |
395 | + } |
396 | + } |
397 | + } |
398 | + } |
399 | + else // no cache |
400 | + { |
401 | + { |
402 | + const std::vector<ArgVarRefs>& argsRefs = theUDF->getArgVarsRefs(); |
403 | + const std::vector<store::Iterator_t>& argWraps = state->theArgWrappers; |
404 | + |
405 | + for (csize i = 0; i < argsRefs.size(); ++i) |
406 | + { |
407 | + if (argWraps[i] != NULL) |
408 | + { |
409 | + const ArgVarRefs& argVarRefs = argsRefs[i]; |
410 | + store::Iterator_t argWrapper; |
411 | + |
412 | if (i < argWraps.size()) |
413 | argWrapper = argWraps[i]; |
414 | - } |
415 | - |
416 | - ArgVarRefs::const_iterator argVarRefsIte = argVarRefs.begin(); |
417 | - ArgVarRefs::const_iterator argVarRefsEnd = argVarRefs.end(); |
418 | - |
419 | - for (; argVarRefsIte != argVarRefsEnd; ++argVarRefsIte) |
420 | - { |
421 | - const LetVarIter_t& argRef = (*argVarRefsIte); |
422 | - assert(argRef != NULL); |
423 | - |
424 | - if (argRef != NULL) |
425 | + |
426 | + ArgVarRefs::const_iterator argVarRefsIte = argVarRefs.begin(); |
427 | + ArgVarRefs::const_iterator argVarRefsEnd = argVarRefs.end(); |
428 | + |
429 | + for (; argVarRefsIte != argVarRefsEnd; ++argVarRefsIte) |
430 | { |
431 | - argRef->bind(argWrapper, *state->thePlanState); |
432 | + const LetVarIter_t& argRef = (*argVarRefsIte); |
433 | + assert(argRef != NULL); |
434 | + |
435 | + if (argRef != NULL) |
436 | + { |
437 | + argRef->bind(argWrapper, *state->thePlanState); |
438 | + } |
439 | } |
440 | } |
441 | } |
442 | } |
443 | - } |
444 | |
445 | - if (lCacheHit) |
446 | - { |
447 | - STACK_PUSH(true, state); |
448 | - } |
449 | - else |
450 | - { |
451 | -#ifdef ZORBA_WITH_DEBUGGER |
452 | DEBUGGER_PUSH_FRAME; |
453 | -#endif |
454 | + |
455 | while (consumeNext(result, state->thePlan, *state->thePlanState)) |
456 | { |
457 | -#ifdef ZORBA_WITH_DEBUGGER |
458 | DEBUGGER_POP_FRAME; |
459 | -#endif |
460 | - |
461 | - insertCacheEntry(state, lKey, result); |
462 | STACK_PUSH(true, state); |
463 | - |
464 | -#ifdef ZORBA_WITH_DEBUGGER |
465 | DEBUGGER_PUSH_FRAME; |
466 | -#endif |
467 | } |
468 | |
469 | -#ifdef ZORBA_WITH_DEBUGGER |
470 | DEBUGGER_POP_FRAME; |
471 | -#endif |
472 | - |
473 | } |
474 | |
475 | STACK_END(state); |
476 | - |
477 | } |
478 | catch (ZorbaException& err) |
479 | { |
480 | |
481 | === modified file 'src/runtime/core/fncall_iterator.h' |
482 | --- src/runtime/core/fncall_iterator.h 2013-05-25 14:36:27 +0000 |
483 | +++ src/runtime/core/fncall_iterator.h 2013-06-16 06:47:28 +0000 |
484 | @@ -23,6 +23,7 @@ |
485 | #include "common/shared_types.h" |
486 | |
487 | #include "runtime/hof/function_item.h" |
488 | +#include "runtime/util/single_item_iterator.h" |
489 | |
490 | #include "context/static_context.h" |
491 | |
492 | @@ -93,15 +94,21 @@ |
493 | class UDFunctionCallIteratorState : public PlanIteratorState |
494 | { |
495 | public: |
496 | - dynamic_context * theLocalDCtx; |
497 | - bool theIsLocalDCtxOwner; |
498 | - PlanIter_t thePlan; |
499 | - PlanState * thePlanState; |
500 | - bool thePlanOpen; |
501 | - uint32_t thePlanStateSize; |
502 | - std::vector<store::Iterator_t> theArgWrappers; |
503 | - store::Index * theCache; |
504 | - std::vector<store::TempSeq_t> theArgValues; |
505 | + dynamic_context * theLocalDCtx; |
506 | + bool theIsLocalDCtxOwner; |
507 | + |
508 | + PlanIter_t thePlan; |
509 | + PlanState * thePlanState; |
510 | + bool thePlanOpen; |
511 | + uint32_t thePlanStateSize; |
512 | + |
513 | + std::vector<store::Iterator_t> theArgWrappers; |
514 | + |
515 | + store::Index * theCache; |
516 | + store::IndexKey * theCacheKey; |
517 | + store::IndexCondition_t theCacheCond; |
518 | + store::IndexProbeIterator_t theCacheProbeIte; |
519 | + std::vector<SingleItemIterator_t> theArgValues; |
520 | |
521 | UDFunctionCallIteratorState(); |
522 | |
523 | @@ -194,7 +201,7 @@ |
524 | void insertCacheEntry( |
525 | UDFunctionCallIteratorState* state, |
526 | std::vector<store::Item_t>& argValues, |
527 | - store::Item_t& udfValue) const; |
528 | + const store::Item_t& udfResult) const; |
529 | }; |
530 | |
531 | |
532 | |
533 | === modified file 'src/runtime/util/item_iterator.cpp' |
534 | --- src/runtime/util/item_iterator.cpp 2013-03-04 21:00:58 +0000 |
535 | +++ src/runtime/util/item_iterator.cpp 2013-06-16 06:47:28 +0000 |
536 | @@ -20,7 +20,7 @@ |
537 | |
538 | namespace zorba { |
539 | |
540 | -ItemIterator::ItemIterator(std::vector<store::Item_t> const &aItems) |
541 | +ItemIterator::ItemIterator(const std::vector<store::Item_t>& aItems) |
542 | : |
543 | theItems(aItems) |
544 | { |
545 | |
546 | === modified file 'src/runtime/util/item_iterator.h' |
547 | --- src/runtime/util/item_iterator.h 2013-03-05 00:45:43 +0000 |
548 | +++ src/runtime/util/item_iterator.h 2013-06-16 06:47:28 +0000 |
549 | @@ -13,8 +13,8 @@ |
550 | * See the License for the specific language governing permissions and |
551 | * limitations under the License. |
552 | */ |
553 | -#ifndef ZORBA_RUNTIME_ITEM_ITERATOR_H2 |
554 | -#define ZORBA_RUNTIME_ITEM_ITERATOR_H2 |
555 | +#ifndef ZORBA_RUNTIME_UTIL_ITEM_ITERATOR |
556 | +#define ZORBA_RUNTIME_UTIL_ITEM_ITERATOR |
557 | |
558 | #include <vector> |
559 | #include "store/api/iterator.h" |
560 | @@ -25,12 +25,14 @@ |
561 | class ItemIterator : public store::Iterator |
562 | { |
563 | private: |
564 | - std::vector<store::Item_t> theItems; |
565 | + std::vector<store::Item_t> theItems; |
566 | std::vector<store::Item_t>::iterator theIterator; |
567 | |
568 | public: |
569 | - ItemIterator(std::vector<store::Item_t> const &aItems); |
570 | + ItemIterator(const std::vector<store::Item_t>& aItems); |
571 | + |
572 | ItemIterator(store::Item_t aItem); |
573 | + |
574 | ItemIterator(); // construct the empty sequence |
575 | |
576 | virtual ~ItemIterator(){} |
577 | |
578 | === added file 'src/runtime/util/single_item_iterator.h' |
579 | --- src/runtime/util/single_item_iterator.h 1970-01-01 00:00:00 +0000 |
580 | +++ src/runtime/util/single_item_iterator.h 2013-06-16 06:47:28 +0000 |
581 | @@ -0,0 +1,80 @@ |
582 | +/* |
583 | + * Copyright 2006-2008 The FLWOR Foundation. |
584 | + * |
585 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
586 | + * you may not use this file except in compliance with the License. |
587 | + * You may obtain a copy of the License at |
588 | + * |
589 | + * http://www.apache.org/licenses/LICENSE-2.0 |
590 | + * |
591 | + * Unless required by applicable law or agreed to in writing, software |
592 | + * distributed under the License is distributed on an "AS IS" BASIS, |
593 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
594 | + * See the License for the specific language governing permissions and |
595 | + * limitations under the License. |
596 | + */ |
597 | +#ifndef ZORBA_RUNTIME_UTIL_SINGLE_ITEM_ITERATOR |
598 | +#define ZORBA_RUNTIME_UTIL_SINGLE_ITEM_ITERATOR |
599 | + |
600 | +#include <vector> |
601 | + |
602 | +#include "store/api/iterator.h" |
603 | + |
604 | +#include "common/shared_types.h" |
605 | + |
606 | +namespace zorba |
607 | +{ |
608 | + |
609 | +class SingleItemIterator : public store::Iterator |
610 | +{ |
611 | +private: |
612 | + store::Item_t theItem; |
613 | + bool theIsDone; |
614 | + |
615 | +public: |
616 | + SingleItemIterator() : theIsDone(true) {} |
617 | + |
618 | + SingleItemIterator(store::Item_t& item) |
619 | + { |
620 | + theIsDone = false; |
621 | + theItem.transfer(item); |
622 | + } |
623 | + |
624 | + virtual ~SingleItemIterator() {} |
625 | + |
626 | + void init(store::Item_t& item) |
627 | + { |
628 | + theIsDone = false; |
629 | + theItem.transfer(item); |
630 | + } |
631 | + |
632 | + void open() {} |
633 | + |
634 | + bool next(store::Item_t& res) |
635 | + { |
636 | + if (theIsDone) |
637 | + return false; |
638 | + |
639 | + res = theItem; |
640 | + theIsDone = true; |
641 | + return true; |
642 | + } |
643 | + |
644 | + void reset() { theIsDone = (theItem == NULL); } |
645 | + |
646 | + void close() { theItem = NULL; theIsDone = true; } |
647 | + |
648 | +#ifndef NDEBUG |
649 | + // toString() debugging method. |
650 | + virtual std::string toString() const { return ""; }; |
651 | +#endif |
652 | +}; |
653 | + |
654 | + |
655 | +typedef rchandle<SingleItemIterator> SingleItemIterator_t; |
656 | + |
657 | + |
658 | +} // namespace zorba |
659 | + |
660 | +#endif |
661 | +/* vim:set et sw=2 ts=2: */ |
662 | |
663 | === added file 'test/rbkt/ExpQueryResults/zorba/udf/cache01.xml.res' |
664 | --- test/rbkt/ExpQueryResults/zorba/udf/cache01.xml.res 1970-01-01 00:00:00 +0000 |
665 | +++ test/rbkt/ExpQueryResults/zorba/udf/cache01.xml.res 2013-06-16 06:47:28 +0000 |
666 | @@ -0,0 +1,6 @@ |
667 | +4 |
668 | + |
669 | + 4 |
670 | + |
671 | + 22 == 484 |
672 | + 22 == 484 |
673 | |
674 | === added file 'test/rbkt/ExpQueryResults/zorba/udf/cache_01.xml.res' |
675 | --- test/rbkt/ExpQueryResults/zorba/udf/cache_01.xml.res 1970-01-01 00:00:00 +0000 |
676 | +++ test/rbkt/ExpQueryResults/zorba/udf/cache_01.xml.res 2013-06-16 06:47:28 +0000 |
677 | @@ -0,0 +1,6 @@ |
678 | +4 |
679 | + |
680 | + 4 |
681 | + |
682 | + 22 == 484 |
683 | + 22 == 484 |
684 | |
685 | === added file 'test/rbkt/Queries/zorba/udf/cache_01.xq' |
686 | --- test/rbkt/Queries/zorba/udf/cache_01.xq 1970-01-01 00:00:00 +0000 |
687 | +++ test/rbkt/Queries/zorba/udf/cache_01.xq 2013-06-16 06:47:28 +0000 |
688 | @@ -0,0 +1,37 @@ |
689 | + |
690 | +declare namespace ann = "http://www.zorba-xquery.com/annotations"; |
691 | + |
692 | +declare function local:dummy() |
693 | +{ |
694 | + () |
695 | +}; |
696 | + |
697 | + |
698 | +declare %ann:cache function local:foo($x as xs:integer) |
699 | +{ |
700 | + if ($x < 10) |
701 | + then $x * $x |
702 | + else if ($x < 20) |
703 | + then local:dummy() |
704 | + else ($x, " == ", $x * $x) |
705 | +}; |
706 | + |
707 | + |
708 | +local:foo(2), |
709 | +" |
710 | +", |
711 | +local:foo(12), |
712 | +" |
713 | +", |
714 | +local:foo(2), |
715 | +" |
716 | +", |
717 | +local:foo(12), |
718 | +" |
719 | +", |
720 | +local:foo(22), |
721 | +" |
722 | +", |
723 | +local:foo(22), |
724 | +" |
725 | +" |
Validation queue starting for merge proposal. zorbatest. lambda. nu:8080/ remotequeue/ markos- scratch- 2013-06- 15T23-03- 13.979Z/ log.html
Log at: http://