Merge lp:~zorba-coders/zorba/feature-transient_maps into lp:zorba

Proposed by Matthias Brantner on 2012-05-18
Status: Merged
Approved by: Matthias Brantner on 2012-06-23
Approved revision: 10851
Merged at revision: 10888
Proposed branch: lp:~zorba-coders/zorba/feature-transient_maps
Merge into: lp:zorba
Diff against target: 1867 lines (+875/-213)
26 files modified
ChangeLog (+1/-0)
modules/com/zorba-xquery/www/modules/store/data-structures/unordered-map.xq (+74/-30)
src/context/dynamic_context.cpp (+69/-0)
src/context/dynamic_context.h (+10/-0)
src/functions/pregenerated/func_maps.cpp (+45/-0)
src/functions/pregenerated/func_maps.h (+36/-0)
src/functions/pregenerated/function_enum.h (+2/-0)
src/runtime/pregenerated/iterator_enum.h (+2/-0)
src/runtime/spec/store/maps.xml (+65/-5)
src/runtime/store/maps_impl.cpp (+302/-156)
src/runtime/store/pregenerated/maps.cpp (+56/-0)
src/runtime/store/pregenerated/maps.h (+66/-1)
src/runtime/visitors/pregenerated/planiter_visitor.h (+10/-0)
src/runtime/visitors/pregenerated/printer_visitor.cpp (+28/-0)
src/runtime/visitors/pregenerated/printer_visitor.h (+6/-0)
src/store/api/index.h (+5/-0)
src/store/api/store.h (+4/-0)
src/store/naive/pul_primitives.cpp (+6/-7)
src/store/naive/simple_index_general.cpp (+2/-2)
src/store/naive/simple_index_general.h (+26/-3)
src/store/naive/store.cpp (+5/-5)
src/store/naive/store.h (+4/-4)
test/rbkt/ExpQueryResults/zorba/store/unordered-map/map7.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/store/unordered-map/transient-map0.xml.res (+1/-0)
test/rbkt/Queries/zorba/store/unordered-map/map7.xq (+22/-0)
test/rbkt/Queries/zorba/store/unordered-map/transient-map0.xq (+27/-0)
To merge this branch: bzr merge lp:~zorba-coders/zorba/feature-transient_maps
Reviewer Review Type Date Requested Status
Matthias Brantner Approve on 2012-06-23
Till Westmann 2012-05-18 Approve on 2012-06-23
Review via email: mp+106287@code.launchpad.net

Commit message

Added support for transient maps in the unordered-maps module.

Description of the change

Added support for transient maps in the unordered-maps module.

A transient map is only available within the execution of the currently active XQuery program. It is not available to any other program that is running in parallel or after the program that created it.

Transient maps can be created using map:create-transient. All other functions are left unchanged and operate on transient and non-transient/persistent maps. Transient and persistent maps can not have the same names.

To post a comment you must log in.
Zorba Build Bot (zorba-buildbot) wrote :

The attempt to merge lp:~zorba-coders/zorba/feature-transient_maps into lp:zorba failed. Below is the output from the failed tests.

CMake Error at /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake:274 (message):
  Validation queue job feature-transient_maps-2012-05-18T00-03-10.458Z is
  finished. The final status was:

  No tests were run - build or configure step must have failed.

  Not commiting changes.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

Zorba Build Bot (zorba-buildbot) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

Zorba Build Bot (zorba-buildbot) wrote :

Validation queue job feature-transient_maps-2012-05-18T00-27-10.419Z is finished. The final status was:

All tests succeeded!

Zorba Build Bot (zorba-buildbot) wrote :

Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1, Needs Fixing < 1, Pending < 1. Got: 2 Pending.

Till Westmann (tillw) wrote :

The docs say that a key can consist of a "set" of atomic values. As the order of the values is relevant "list" or "tuple" might be better.

As the parameters for insert, get, etc. are anyAtomicType? an empty sequence can be passed in, but the doc does not say how that is handled.

I've extended the test to cover a little more of the functionality.

review: Needs Fixing
Zorba Build Bot (zorba-buildbot) wrote :

Attempt to merge into lp:zorba failed due to conflicts:

text conflict in ChangeLog

Zorba Build Bot (zorba-buildbot) wrote :

Validation queue job feature-transient_maps-2012-06-20T18-41-00.67Z is finished. The final status was:

All tests succeeded!

Zorba Build Bot (zorba-buildbot) wrote :

Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1, Needs Fixing < 1, Pending < 1. Got: 1 Needs Fixing, 1 Pending.

Till Westmann (tillw) wrote :

Modified the documentation and added another test.

Unfortunately this test (zorba/store/unordered-map/map7.xq) crashes (SEGV).

review: Needs Fixing
Till Westmann (tillw) wrote :

Fixed the crashing test and addressed all of my review comments.

review: Approve
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue job feature-transient_maps-2012-06-23T00-39-00.771Z is finished. The final status was:

All tests succeeded!

Zorba Build Bot (zorba-buildbot) wrote :

Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1, Needs Fixing < 1, Pending < 1. Got: 1 Approve, 1 Pending.

review: Approve
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue job feature-transient_maps-2012-06-23T01-25-57.278Z is finished. The final status was:

All tests succeeded!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2012-06-22 08:38:46 +0000
3+++ ChangeLog 2012-06-23 00:29:20 +0000
4@@ -5,6 +5,7 @@
5
6 New Features:
7 * Implemented latest W3C soec for group by clause
8+ * Added support for transient maps to the http://www.zorba-xquery.com/modules/store/data-structures/unordered-map module.
9
10 Optimizations:
11 * Small optimization of comparison operations.
12
13=== modified file 'modules/com/zorba-xquery/www/modules/store/data-structures/unordered-map.xq'
14--- modules/com/zorba-xquery/www/modules/store/data-structures/unordered-map.xq 2012-06-18 10:06:47 +0000
15+++ modules/com/zorba-xquery/www/modules/store/data-structures/unordered-map.xq 2012-06-23 00:29:20 +0000
16@@ -1,7 +1,6 @@
17 xquery version "3.0";
18-
19 (:
20- : Copyright 2006-2009 The FLWOR Foundation.
21+ : Copyright 2006-2012 The FLWOR Foundation.
22 :
23 : Licensed under the Apache License, Version 2.0 (the "License");
24 : you may not use this file except in compliance with the License.
25@@ -17,17 +16,20 @@
26 :)
27
28 (:~
29- : This module defines a set of functions for working with
30- : maps. A map is identified by a QName and can
31- : be created using the map:create function and deleted
32- : using the map:delete function, respectively. However, its
33- : actual lifetime depends on the particular store implementation.
34- :
35- : The key of a particular entry in the map can consist
36- : out of a set of atomic values (called attributes).
37- : The actual type of each attribute can be determined when the
38- : map is created. The value can be an arbitrary sequence
39- : of items.
40+ : <p>This module defines a set of functions for working with maps. A map
41+ : is identified by a QName and can be created using the map:create or
42+ : map:create-transient functions and deleted using the map:delete function,
43+ : respectively.</p>
44+ :
45+ : <p>The lifetime of a transient map is limited by the execution of the
46+ : current XQuery program. A non-transient (or persistent) map lives until
47+ : it is explicitly deleted. Accordingly, it's also available
48+ : to other XQuery programs.</p>
49+ :
50+ : <p>The key of a particular entry in the map can consist of a tuple of
51+ : atomic values (called attributes). The actual type of each attribute
52+ : is determined when the map is created. The value of each attribute can
53+ : be an arbitrary sequence of items.</p>
54 :
55 : @see <a href="../../html/data_lifecycle.html">Data Lifecycle</a>
56 : @see <a href="www.zorba-xquery.com_errors.html">http://www.zorba-xquery.com/errors</a>
57@@ -46,11 +48,10 @@
58 declare option ver:module-version "2.0";
59
60 (:~
61- : Create a map with a given name and a set of types for
62- : each key attribute. Note that the function is variadic
63- : and might take an arbitrary amount of types for the key
64- : attributes. Also note that the function is sequential
65- : and immediately creates the map in the store.
66+ : Create a map with a given name and a set of type identifiers for each key
67+ : attribute. Note that the function is variadic and might take an arbitrary
68+ : number of type identifiers for the key attributes. Also note that the
69+ : function is sequential and immediately creates the map in the store.
70 :
71 : @param $name the name of the map
72 : @param $key-type an arbitrary number of types, one
73@@ -68,6 +69,26 @@
74 $key-type as xs:QName) as empty-sequence() external;
75
76 (:~
77+ : Create a transient map with a given name and a set of type identifiers
78+ : for each key attribute. Note that the function is variadic and might
79+ : take an arbitrary number of type identifiers for the key attributes.
80+ :
81+ : @param $name the name of the map
82+ : @param $key-type an arbitrary number of types, one
83+ : for each key attribute.
84+ :
85+ : @return the function is sequential and immediately creates
86+ : the corresponding map but returns the empty-sequence.
87+ :
88+ : @error err:XPTY0004 if any of the attribute types is not a subtype of
89+ : xs:anyAtomicType.
90+ : @error zerr:ZSTR0001 if a map with the given name already exists.
91+ :)
92+declare %an:variadic %an:sequential function map:create-transient(
93+ $name as xs:QName,
94+ $key-type as xs:QName) as empty-sequence() external;
95+
96+(:~
97 : Destroys the map with the given name.
98 :
99 : @param $name the name of the map to delete
100@@ -81,13 +102,17 @@
101 $name as xs:QName) as empty-sequence() external;
102
103 (:~
104- : Inserts a new entry into the map with the given
105- : name. Note that the function is variadic
106- : and might take an arbitrary amount of key attributes.
107- : If an entry with the given key already exists in the
108- : map, the value sequences of the existing entry and the
109- : sequence passed using $value argument are concatenated.
110- :
111+ : Inserts a new entry into the map with the given name. Note that the
112+ : function is variadic and might take an arbitrary number of key attributes.
113+ : If an entry with the given key already exists in the map, the value
114+ : sequences of the existing entry and the sequence passed using $value
115+ : argument are concatenated.
116+ :
117+ : Note that it is possible to insert entries with empty key attributes.
118+ : However as the getting the entries is based on the "eq" comparison and
119+ : as "eq" with an empty sequence always return false, it is not possible
120+ : to retrieve these entries.
121+ :
122 : @param $name the name of the map
123 : @param $value the value of the entry to insert
124 : @param $key an arbitrary number of key attributes.
125@@ -113,8 +138,12 @@
126 $key as xs:anyAtomicType?) as empty-sequence() external;
127
128 (:~
129- : Returns the value of the entry with the given key
130- : from the map.
131+ : Returns the value of the entry with the given key from the map.
132+ :
133+ : Note that it is possible to insert entries with empty key attributes.
134+ : However as the getting the entries is based on the "eq" comparison and
135+ : as "eq" with an empty sequence always return false, it is not possible
136+ : to retrieve these entries.
137 :
138 : @param $name the name of the map
139 : @param an arbitrary number of search key attributes.
140@@ -140,6 +169,11 @@
141 (:~
142 : Removes an entry identified by the given key from the map.
143 :
144+ : Note that it is possible to insert entries with empty key attributes.
145+ : However as the removing the entries is based on the "eq" comparison and
146+ : as "eq" with an empty sequence always return false, it is not possible
147+ : to remove these entries.
148+ :
149 : @param $name the name of the map
150 : @param an arbitrary number of search key attributes.
151 :
152@@ -156,7 +190,6 @@
153 : specified when creating the map.
154 :
155 : @see map:create
156- :
157 :)
158 declare %an:variadic %an:sequential function map:remove(
159 $name as xs:QName,
160@@ -199,8 +232,7 @@
161 :
162 : @error zerr:ZDDY0023 if a map with the given name does not exist.
163 :)
164-declare function map:size(
165- $name as xs:QName) as xs:integer external;
166+declare function map:size($name as xs:QName) as xs:integer external;
167
168 (:~
169 : The function returns a sequence of QNames of the maps that are
170@@ -210,3 +242,15 @@
171 :
172 :)
173 declare function map:available-maps() as xs:QName* external;
174+
175+(:~
176+ : The function returns true if the map identified by the given QName
177+ : is transient, false otherwise.
178+ :
179+ : @param $name the name of the map
180+ :
181+ : @return true if the map is transient, false otherwise.
182+ :
183+ : @error zerr:ZDDY0023 if a map with the given name does not exist.
184+ :)
185+declare function map:is-transient($name as xs:QName) as xs:boolean external;
186
187=== modified file 'src/context/dynamic_context.cpp'
188--- src/context/dynamic_context.cpp 2012-06-18 10:06:47 +0000
189+++ src/context/dynamic_context.cpp 2012-06-23 00:29:20 +0000
190@@ -130,6 +130,7 @@
191 theParent(NULL),
192 keymap(NULL),
193 theAvailableIndices(NULL),
194+ theAvailableMaps(NULL),
195 theEnvironmentVariables(NULL),
196 theDocLoadingUserTime(0.0),
197 theDocLoadingTime(0)
198@@ -175,6 +176,9 @@
199
200 if (theAvailableIndices)
201 delete theAvailableIndices;
202+
203+ if (theAvailableMaps)
204+ delete theAvailableMaps;
205 }
206
207
208@@ -728,6 +732,71 @@
209 /*******************************************************************************
210
211 ********************************************************************************/
212+store::Index* dynamic_context::getMap(store::Item* qname) const
213+{
214+ if (theAvailableMaps == NULL)
215+ return NULL;
216+
217+ store::Index_t map;
218+
219+ if (theAvailableMaps->get(qname, map))
220+ {
221+ return map.getp();
222+ }
223+ else
224+ {
225+ return NULL;
226+ }
227+}
228+
229+
230+/*******************************************************************************
231+
232+********************************************************************************/
233+void dynamic_context::bindMap(
234+ store::Item* qname,
235+ store::Index_t& map)
236+{
237+ if (theAvailableMaps == NULL)
238+ theAvailableMaps = new IndexMap(HashMapItemPointerCmp(0, NULL), 8, false);
239+
240+ if (!theAvailableMaps->insert(qname, map))
241+ {
242+ ZORBA_ASSERT(false);
243+ }
244+}
245+
246+
247+/*******************************************************************************
248+
249+********************************************************************************/
250+void dynamic_context::unbindMap(store::Item* qname)
251+{
252+ if (theAvailableMaps != NULL)
253+ theAvailableMaps->erase(qname);
254+}
255+
256+
257+/*******************************************************************************
258+
259+********************************************************************************/
260+void dynamic_context::getMapNames(std::vector<store::Item_t>& names) const
261+{
262+ if (theAvailableMaps == NULL)
263+ return;
264+
265+ for (IndexMap::iterator lIter = theAvailableMaps->begin();
266+ lIter != theAvailableMaps->end();
267+ ++lIter)
268+ {
269+ names.push_back(lIter.getKey());
270+ }
271+}
272+
273+
274+/*******************************************************************************
275+
276+********************************************************************************/
277 store::Iterator_t dynamic_context::listActiveICNames()
278 {
279 return GENV_STORE.listActiveICNames();
280
281=== modified file 'src/context/dynamic_context.h'
282--- src/context/dynamic_context.h 2012-06-18 10:06:47 +0000
283+++ src/context/dynamic_context.h 2012-06-23 00:29:20 +0000
284@@ -123,6 +123,8 @@
285
286 IndexMap * theAvailableIndices;
287
288+ IndexMap * theAvailableMaps;
289+
290 //MODIFY
291 EnvVarMap * theEnvironmentVariables;
292
293@@ -204,6 +206,14 @@
294
295 void unbindIndex(store::Item* qname);
296
297+ store::Index* getMap(store::Item* qname) const;
298+
299+ void bindMap(store::Item* qname, store::Index_t& index);
300+
301+ void unbindMap(store::Item* qname);
302+
303+ void getMapNames(std::vector<store::Item_t>& names) const;
304+
305 /**
306 * Lists all active integrity constraints.
307 */
308
309=== modified file 'src/functions/pregenerated/func_maps.cpp'
310--- src/functions/pregenerated/func_maps.cpp 2012-06-18 10:06:47 +0000
311+++ src/functions/pregenerated/func_maps.cpp 2012-06-23 00:29:20 +0000
312@@ -41,6 +41,16 @@
313 return new MapCreateIterator(sctx, loc, argv);
314 }
315
316+PlanIter_t zorba_store_data_structure_unordered_map_create_transient::codegen(
317+ CompilerCB*,
318+ static_context* sctx,
319+ const QueryLoc& loc,
320+ std::vector<PlanIter_t>& argv,
321+ expr& ann) const
322+{
323+ return new MapCreateTransientIterator(sctx, loc, argv);
324+}
325+
326 PlanIter_t zorba_store_data_structure_unordered_map_delete::codegen(
327 CompilerCB*,
328 static_context* sctx,
329@@ -111,6 +121,16 @@
330 return new AvailableMapsIterator(sctx, loc, argv);
331 }
332
333+PlanIter_t zorba_store_data_structure_unordered_map_is_transient::codegen(
334+ CompilerCB*,
335+ static_context* sctx,
336+ const QueryLoc& loc,
337+ std::vector<PlanIter_t>& argv,
338+ expr& ann) const
339+{
340+ return new MapIsTransientIterator(sctx, loc, argv);
341+}
342+
343 void populate_context_maps(static_context* sctx)
344 {
345
346@@ -129,6 +149,19 @@
347
348
349 {
350+ std::vector<xqtref_t> lParamTypes;
351+ lParamTypes.push_back(GENV_TYPESYSTEM.QNAME_TYPE_ONE);
352+ lParamTypes.push_back(GENV_TYPESYSTEM.QNAME_TYPE_ONE);DECL_WITH_KIND(sctx, zorba_store_data_structure_unordered_map_create_transient,
353+ (createQName("http://www.zorba-xquery.com/modules/store/data-structures/unordered-map","","create-transient"),
354+ lParamTypes, GENV_TYPESYSTEM.EMPTY_TYPE, true),
355+ FunctionConsts::ZORBA_STORE_DATA_STRUCTURE_UNORDERED_MAP_CREATE_TRANSIENT_N);
356+
357+ }
358+
359+
360+
361+
362+ {
363 DECL_WITH_KIND(sctx, zorba_store_data_structure_unordered_map_delete,
364 (createQName("http://www.zorba-xquery.com/modules/store/data-structures/unordered-map","","delete"),
365 GENV_TYPESYSTEM.QNAME_TYPE_ONE,
366@@ -212,6 +245,18 @@
367
368 }
369
370+
371+
372+
373+ {
374+ DECL_WITH_KIND(sctx, zorba_store_data_structure_unordered_map_is_transient,
375+ (createQName("http://www.zorba-xquery.com/modules/store/data-structures/unordered-map","","is-transient"),
376+ GENV_TYPESYSTEM.QNAME_TYPE_ONE,
377+ GENV_TYPESYSTEM.BOOLEAN_TYPE_ONE),
378+ FunctionConsts::ZORBA_STORE_DATA_STRUCTURE_UNORDERED_MAP_IS_TRANSIENT_1);
379+
380+ }
381+
382 }
383
384
385
386=== modified file 'src/functions/pregenerated/func_maps.h'
387--- src/functions/pregenerated/func_maps.h 2012-06-18 10:06:47 +0000
388+++ src/functions/pregenerated/func_maps.h 2012-06-23 00:29:20 +0000
389@@ -57,6 +57,25 @@
390 };
391
392
393+//zorba-store-data-structure-unordered-map:create-transient
394+class zorba_store_data_structure_unordered_map_create_transient : public function
395+{
396+public:
397+ zorba_store_data_structure_unordered_map_create_transient(const signature& sig, FunctionConsts::FunctionKind kind)
398+ :
399+ function(sig, kind)
400+ {
401+
402+ }
403+
404+ unsigned short getScriptingKind() const { return SEQUENTIAL_FUNC_EXPR; }
405+
406+ bool accessesDynCtx() const { return true; }
407+
408+ CODEGEN_DECL();
409+};
410+
411+
412 //zorba-store-data-structure-unordered-map:delete
413 class zorba_store_data_structure_unordered_map_delete : public function
414 {
415@@ -182,6 +201,23 @@
416 };
417
418
419+//zorba-store-data-structure-unordered-map:is-transient
420+class zorba_store_data_structure_unordered_map_is_transient : public function
421+{
422+public:
423+ zorba_store_data_structure_unordered_map_is_transient(const signature& sig, FunctionConsts::FunctionKind kind)
424+ :
425+ function(sig, kind)
426+ {
427+
428+ }
429+
430+ bool accessesDynCtx() const { return true; }
431+
432+ CODEGEN_DECL();
433+};
434+
435+
436 } //namespace zorba
437
438
439
440=== modified file 'src/functions/pregenerated/function_enum.h'
441--- src/functions/pregenerated/function_enum.h 2012-06-18 10:06:47 +0000
442+++ src/functions/pregenerated/function_enum.h 2012-06-23 00:29:20 +0000
443@@ -401,6 +401,7 @@
444 ZORBA_STORE_DOCUMENTS_AVAILABLE_DOCUMENTS_0,
445 ZORBA_STORE_DOCUMENTS_IS_AVAILABLE_DOCUMENT_1,
446 ZORBA_STORE_DATA_STRUCTURE_UNORDERED_MAP_CREATE_N,
447+ ZORBA_STORE_DATA_STRUCTURE_UNORDERED_MAP_CREATE_TRANSIENT_N,
448 ZORBA_STORE_DATA_STRUCTURE_UNORDERED_MAP_DELETE_1,
449 ZORBA_STORE_DATA_STRUCTURE_UNORDERED_MAP_GET_N,
450 ZORBA_STORE_DATA_STRUCTURE_UNORDERED_MAP_INSERT_N,
451@@ -408,6 +409,7 @@
452 ZORBA_STORE_DATA_STRUCTURE_UNORDERED_MAP_KEYS_1,
453 ZORBA_STORE_DATA_STRUCTURE_UNORDERED_MAP_SIZE_1,
454 ZORBA_STORE_DATA_STRUCTURE_UNORDERED_MAP_AVAILABLE_MAPS_0,
455+ ZORBA_STORE_DATA_STRUCTURE_UNORDERED_MAP_IS_TRANSIENT_1,
456 FN_CODEPOINTS_TO_STRING_1,
457 FN_STRING_TO_CODEPOINTS_1,
458 FN_COMPARE_2,
459
460=== modified file 'src/runtime/pregenerated/iterator_enum.h'
461--- src/runtime/pregenerated/iterator_enum.h 2012-06-18 10:06:47 +0000
462+++ src/runtime/pregenerated/iterator_enum.h 2012-06-23 00:29:20 +0000
463@@ -300,6 +300,7 @@
464 TYPE_AvailableDocumentsIterator,
465 TYPE_IsAvailableDocumentIterator,
466 TYPE_MapCreateIterator,
467+ TYPE_MapCreateTransientIterator,
468 TYPE_MapDestroyIterator,
469 TYPE_MapGetIterator,
470 TYPE_MapInsertIterator,
471@@ -307,6 +308,7 @@
472 TYPE_MapKeysIterator,
473 TYPE_MapSizeIterator,
474 TYPE_AvailableMapsIterator,
475+ TYPE_MapIsTransientIterator,
476 TYPE_CodepointsToStringIterator,
477 TYPE_StringToCodepointsIterator,
478 TYPE_CompareStrIterator,
479
480=== modified file 'src/runtime/spec/store/maps.xml'
481--- src/runtime/spec/store/maps.xml 2012-06-18 10:06:47 +0000
482+++ src/runtime/spec/store/maps.xml 2012-06-23 00:29:20 +0000
483@@ -12,12 +12,13 @@
484 xsi:schemaLocation="http://www.zorba-xquery.com ../runtime.xsd">
485
486 <zorba:source>
487- <zorba:include form="Quoted">store/api/iterator.h</zorba:include>
488- <zorba:include form="Quoted">store/api/index.h</zorba:include>
489+ <zorba:include form="Quoted">store/api/iterator.h</zorba:include>
490+ <zorba:include form="Quoted">store/api/index.h</zorba:include>
491 </zorba:source>
492
493 <zorba:header>
494- <zorba:include form="Quoted">store/api/index.h</zorba:include>
495+ <zorba:include form="Quoted">store/api/index.h</zorba:include>
496+ <zorba:include form="Angle-bracket">vector</zorba:include>
497 </zorba:header>
498
499
500@@ -54,6 +55,35 @@
501 /*******************************************************************************
502 ********************************************************************************/
503 -->
504+<zorba:iterator name="MapCreateTransientIterator" >
505+
506+ <zorba:description author="Matthias Brantner">
507+ </zorba:description>
508+
509+ <zorba:function>
510+
511+ <zorba:signature
512+ variadic="true"
513+ localname="create-transient"
514+ prefix="zorba-store-data-structure-unordered-map">
515+ <zorba:param>xs:QName</zorba:param> <!-- name of the hashmap -->
516+ <zorba:param>xs:QName</zorba:param> <!-- list of key types -->
517+ <zorba:output>empty-sequence()</zorba:output>
518+ </zorba:signature>
519+
520+ <zorba:methods>
521+ <zorba:getScriptingKind returnValue="SEQUENTIAL_FUNC_EXPR"/>
522+ <zorba:accessesDynCtx returnValue="true"/>
523+ </zorba:methods>
524+
525+ </zorba:function>
526+
527+</zorba:iterator>
528+
529+<!--
530+/*******************************************************************************
531+********************************************************************************/
532+-->
533 <zorba:iterator name="MapDestroyIterator" >
534
535 <zorba:description author="Matthias Brantner">
536@@ -238,10 +268,40 @@
537 </zorba:function>
538
539 <zorba:state generateInit="false" generateReset="false" generateDestructor="false">
540- <zorba:member type="store::Iterator_t" name="nameItState"
541- brief="the current iterator"/>
542+ <zorba:member type="store::Iterator_t"
543+ name="persistentMapNamesIter"
544+ brief="the current iterator"/>
545+ <zorba:member type="std::vector&lt;store::Item_t>"
546+ name="transientMapNames" brief="all the transient map names"/>
547+ <zorba:member type="std::vector&lt;store::Item_t>::const_iterator"
548+ name="transientMapNamesIter"
549+ brief="the current iterator"/>
550 </zorba:state>
551
552 </zorba:iterator>
553
554+<!--
555+/*******************************************************************************
556+********************************************************************************/
557+-->
558+<zorba:iterator name="MapIsTransientIterator" >
559+
560+ <zorba:description author="Matthias Brantner">
561+ </zorba:description>
562+
563+ <zorba:function>
564+
565+ <zorba:signature localname="is-transient" prefix="zorba-store-data-structure-unordered-map">
566+ <zorba:param>xs:QName</zorba:param>
567+ <zorba:output>xs:boolean</zorba:output>
568+ </zorba:signature>
569+
570+ <zorba:methods>
571+ <zorba:accessesDynCtx returnValue="true"/>
572+ </zorba:methods>
573+
574+ </zorba:function>
575+
576+</zorba:iterator>
577+
578 </zorba:iterators>
579
580=== modified file 'src/runtime/store/maps_impl.cpp'
581--- src/runtime/store/maps_impl.cpp 2012-06-18 10:06:47 +0000
582+++ src/runtime/store/maps_impl.cpp 2012-06-23 00:29:20 +0000
583@@ -1,5 +1,5 @@
584 /*
585- * Copyright 2006-2008 The FLWOR Foundation.
586+ * Copyright 2006-2012 The FLWOR Foundation.
587 *
588 * Licensed under the Apache License, Version 2.0 (the "License");
589 * you may not use this file except in compliance with the License.
590@@ -16,6 +16,7 @@
591 #include "stdafx.h"
592
593 #include "diagnostics/assert.h"
594+#include "diagnostics/util_macros.h"
595 #include "diagnostics/xquery_diagnostics.h"
596
597 #include "zorbatypes/URI.h"
598@@ -25,6 +26,7 @@
599 #include "runtime/store/maps.h"
600
601 #include "context/static_context.h"
602+#include "context/dynamic_context.h"
603 #include "context/namespace_context.h"
604
605 #include "store/api/pul.h"
606@@ -44,12 +46,9 @@
607
608 namespace zorba {
609
610-#define RAISE_ERROR(errcode, loc, params) \
611- throw XQUERY_EXCEPTION(errcode, \
612- params, \
613- ERROR_LOC(loc));
614-
615-static void
616+/*******************************************************************************
617+********************************************************************************/
618+void
619 castOrCheckIndexType(
620 store::Item_t& aKeyItem,
621 const store::Item_t& aKeyType,
622@@ -101,50 +100,105 @@
623 }
624 }
625 }
626-
627+
628
629 /*******************************************************************************
630 ********************************************************************************/
631-bool
632-MapCreateIterator::nextImpl(
633- store::Item_t& result,
634- PlanState& aPlanState) const
635+void
636+checkMapTypes(
637+ std::vector<store::Item_t>& aTypes,
638+ const store::Item_t& aMapName,
639+ const QueryLoc& aLoc)
640 {
641- store::Item_t lQName;
642- std::vector<store::Item_t> lTypes;
643- std::vector<zstring> lCollations;
644- std::auto_ptr<store::PUL> lPul;
645- long lTimezone = 0;
646 xqtref_t lAnyAtomicType, lIndexKeyType;
647- size_t i;
648-
649- PlanIteratorState* state;
650- DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
651-
652- consumeNext(lQName, theChildren[0].getp(), aPlanState);
653-
654- lTypes.resize(theChildren.size() - 1);
655- lCollations.resize(theChildren.size() - 1);
656- for (i = 1; i < theChildren.size(); ++i)
657+
658+ for (size_t i = 0; i < aTypes.size(); ++i)
659 {
660- consumeNext(lTypes[i-1], theChildren[i].getp(), aPlanState);
661-
662 lAnyAtomicType = GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_ONE;
663 lIndexKeyType = GENV_TYPESYSTEM.create_named_type(
664- lTypes[i-1].getp(), TypeConstants::QUANT_ONE, loc);
665+ aTypes[i].getp(), TypeConstants::QUANT_ONE, aLoc);
666
667 if (lIndexKeyType != NULL &&
668 !TypeOps::is_subtype(&GENV_TYPESYSTEM,
669 *lIndexKeyType, *lAnyAtomicType))
670 {
671- RAISE_ERROR(err::XPTY0004, loc,
672+ RAISE_ERROR(err::XPTY0004, aLoc,
673 ERROR_PARAMS(ZED(SearchKeyTypeMismatch_234),
674 *lAnyAtomicType,
675- lQName->getStringValue(),
676+ aMapName->getStringValue(),
677 *lIndexKeyType)
678 );
679 }
680 }
681+}
682+
683+
684+/*******************************************************************************
685+********************************************************************************/
686+bool
687+getMap(
688+ const store::Item_t& aName,
689+ const QueryLoc& aLoc,
690+ dynamic_context* aContext,
691+ store::Index*& aIndex)
692+{
693+ aIndex = GENV_STORE.getMap(aName);
694+
695+ if (aIndex) return true;
696+
697+ aIndex = aContext->getMap(aName.getp());
698+
699+ if (!aIndex)
700+ {
701+ RAISE_ERROR(
702+ zerr::ZDDY0023_INDEX_DOES_NOT_EXIST,
703+ aLoc,
704+ ERROR_PARAMS( aName->getStringValue() )
705+ );
706+ }
707+
708+ return false;
709+}
710+
711+
712+
713+/*******************************************************************************
714+********************************************************************************/
715+bool
716+MapCreateIterator::nextImpl(
717+ store::Item_t& result,
718+ PlanState& aPlanState) const
719+{
720+ store::Item_t lQName;
721+ std::vector<store::Item_t> lTypes;
722+ std::vector<zstring> lCollations;
723+ std::auto_ptr<store::PUL> lPul;
724+ long lTimezone = 0;
725+
726+ PlanIteratorState* state;
727+ DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
728+
729+ consumeNext(lQName, theChildren[0].getp(), aPlanState);
730+
731+ if (GENV_STORE.getMap(lQName)
732+ || aPlanState.theLocalDynCtx->getMap(lQName.getp()))
733+ {
734+ RAISE_ERROR(
735+ zerr::ZSTR0001_INDEX_ALREADY_EXISTS,
736+ loc,
737+ ERROR_PARAMS( lQName->getStringValue() )
738+ );
739+ }
740+
741+ lCollations.resize(theChildren.size() - 1);
742+ lTypes.resize(theChildren.size() - 1);
743+
744+ for (size_t i = 1; i < theChildren.size(); ++i)
745+ {
746+ consumeNext(lTypes[i-1], theChildren[i].getp(), aPlanState);
747+ }
748+
749+ checkMapTypes(lTypes, lQName, loc);
750
751 lPul.reset(GENV_ITEMFACTORY->createPendingUpdateList());
752 lPul->addCreateHashMap(&loc, lQName, lTypes, lCollations, lTimezone);
753@@ -165,40 +219,86 @@
754 /*******************************************************************************
755 ********************************************************************************/
756 bool
757+MapCreateTransientIterator::nextImpl(
758+ store::Item_t& result,
759+ PlanState& aPlanState) const
760+{
761+ store::Item_t lQName;
762+ store::IndexSpecification lSpec;
763+ store::Index_t lIndex;
764+ std::vector<std::string> lCollations;
765+
766+ PlanIteratorState* state;
767+ DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
768+
769+ consumeNext(lQName, theChildren[0].getp(), aPlanState);
770+
771+ if (GENV_STORE.getMap(lQName)
772+ || aPlanState.theLocalDynCtx->getMap(lQName.getp()))
773+ {
774+ RAISE_ERROR(
775+ zerr::ZSTR0001_INDEX_ALREADY_EXISTS,
776+ loc,
777+ ERROR_PARAMS( lQName->getStringValue() )
778+ );
779+ }
780+
781+ lCollations.resize(theChildren.size() - 1);
782+ lSpec.theKeyTypes.resize(theChildren.size() - 1);
783+
784+ for (size_t i = 1; i < theChildren.size(); ++i)
785+ {
786+ consumeNext(lSpec.theKeyTypes[i-1], theChildren[i].getp(), aPlanState);
787+ }
788+
789+ checkMapTypes(lSpec.theKeyTypes, lQName, loc);
790+
791+ lSpec.theNumKeyColumns = lSpec.theKeyTypes.size();
792+ lSpec.theIsTemp = true;
793+ lSpec.theCollations = lCollations;
794+ lSpec.theTimezone = 0;
795+
796+ lIndex = GENV_STORE.createMap(lQName, lSpec);
797+
798+ aPlanState.theLocalDynCtx->bindMap(lIndex->getName(), lIndex);
799+
800+ result = NULL;
801+
802+ STACK_END(state);
803+}
804+
805+
806+/*******************************************************************************
807+********************************************************************************/
808+bool
809 MapDestroyIterator::nextImpl(
810 store::Item_t& result,
811 PlanState& aPlanState) const
812 {
813 store::Item_t lQName;
814- std::auto_ptr<store::PUL> lPul;
815- store::Index_t lIndex;
816+ store::Index* lIndex;
817
818 PlanIteratorState* state;
819 DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
820
821 consumeNext(lQName, theChildren[0].getp(), aPlanState);
822
823- lIndex = GENV_STORE.getMap(lQName);
824-
825- if (!lIndex)
826- {
827- throw XQUERY_EXCEPTION(
828- zerr::ZDDY0023_INDEX_DOES_NOT_EXIST,
829- ERROR_PARAMS( lQName->getStringValue() ),
830- ERROR_LOC( loc )
831- );
832- }
833-
834-
835- lPul.reset(GENV_ITEMFACTORY->createPendingUpdateList());
836- lPul->addDestroyHashMap(&loc, lQName);
837-
838- apply_updates(
839- aPlanState.theCompilerCB,
840- aPlanState.theGlobalDynCtx,
841- theSctx,
842- lPul.get(),
843- loc);
844+ if (getMap(lQName, loc, aPlanState.theLocalDynCtx, lIndex))
845+ {
846+ std::auto_ptr<store::PUL> lPul(GENV_ITEMFACTORY->createPendingUpdateList());
847+ lPul->addDestroyHashMap(&loc, lQName);
848+
849+ apply_updates(
850+ aPlanState.theCompilerCB,
851+ aPlanState.theGlobalDynCtx,
852+ theSctx,
853+ lPul.get(),
854+ loc);
855+ }
856+ else
857+ {
858+ aPlanState.theLocalDynCtx->unbindMap(lQName.getp());
859+ }
860
861 result = NULL;
862
863@@ -224,29 +324,20 @@
864
865 consumeNext(lQName, theChildren[0].getp(), aPlanState);
866
867- lIndex = GENV_STORE.getMap(lQName);
868-
869- if (!lIndex)
870- {
871- throw XQUERY_EXCEPTION(
872- zerr::ZDDY0023_INDEX_DOES_NOT_EXIST,
873- ERROR_PARAMS( lQName->getStringValue() ),
874- ERROR_LOC( loc )
875- );
876- }
877+ getMap(lQName, loc, aPlanState.theLocalDynCtx, lIndex);
878
879 lSpec = lIndex->getSpecification();
880
881 if (lSpec.getNumColumns() != theChildren.size() - 1)
882 {
883- throw XQUERY_EXCEPTION(
884+ RAISE_ERROR(
885 zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS,
886+ loc,
887 ERROR_PARAMS(
888 lQName->getStringValue(),
889 "map",
890 theChildren.size() - 1,
891- lSpec.getNumColumns() ),
892- ERROR_LOC( loc )
893+ lSpec.getNumColumns() )
894 );
895 }
896
897@@ -293,63 +384,85 @@
898 {
899 store::Item_t lQName;
900 std::vector<store::Item_t> lKey;
901- store::Iterator_t lValue;
902- std::auto_ptr<store::PUL> lPul;
903 store::IndexSpecification lSpec;
904- store::Index_t lIndex;
905+ store::Index* lIndex;
906+ bool lPersistent;
907
908 PlanIteratorState* state;
909 DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
910
911 consumeNext(lQName, theChildren[0].getp(), aPlanState);
912
913- lIndex = GENV_STORE.getMap(lQName);
914-
915- if (!lIndex)
916- {
917- throw XQUERY_EXCEPTION(
918- zerr::ZDDY0023_INDEX_DOES_NOT_EXIST,
919- ERROR_PARAMS( lQName->getStringValue() ),
920- ERROR_LOC( loc )
921- );
922- }
923+ lPersistent = getMap(lQName, loc, aPlanState.theLocalDynCtx, lIndex);
924
925 lSpec = lIndex->getSpecification();
926
927 if (lSpec.getNumColumns() != theChildren.size() - 2)
928 {
929- throw XQUERY_EXCEPTION(
930+ RAISE_ERROR(
931 zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS,
932+ loc,
933 ERROR_PARAMS(
934 lQName->getStringValue(),
935 "map",
936 theChildren.size() - 2,
937- lSpec.getNumColumns() ),
938- ERROR_LOC( loc )
939+ lSpec.getNumColumns() )
940 );
941 }
942
943- lValue = new PlanIteratorWrapper(theChildren[1], aPlanState);
944-
945 lKey.resize(theChildren.size() - 2);
946 for (size_t i = 2; i < theChildren.size(); ++i)
947 {
948 if (consumeNext(lKey[i-2], theChildren[i].getp(), aPlanState))
949 {
950 namespace_context tmp_ctx(theSctx);
951- castOrCheckIndexType(lKey[i-2], lSpec.theKeyTypes[i-2], lQName, &tmp_ctx, loc);
952- }
953- }
954-
955- lPul.reset(GENV_ITEMFACTORY->createPendingUpdateList());
956- lPul->addInsertIntoHashMap(&loc, lQName, lKey, lValue);
957-
958- apply_updates(
959- aPlanState.theCompilerCB,
960- aPlanState.theGlobalDynCtx,
961- theSctx,
962- lPul.get(),
963- loc);
964+ castOrCheckIndexType(
965+ lKey[i-2],
966+ lSpec.theKeyTypes[i-2],
967+ lQName,
968+ &tmp_ctx,
969+ loc);
970+ }
971+ }
972+
973+ if (lPersistent)
974+ {
975+ std::auto_ptr<store::PUL> lPul;
976+ store::Iterator_t lValue
977+ = new PlanIteratorWrapper(theChildren[1], aPlanState);
978+
979+ lPul.reset(GENV_ITEMFACTORY->createPendingUpdateList());
980+ lPul->addInsertIntoHashMap(&loc, lQName, lKey, lValue);
981+
982+ apply_updates(
983+ aPlanState.theCompilerCB,
984+ aPlanState.theGlobalDynCtx,
985+ theSctx,
986+ lPul.get(),
987+ loc);
988+ }
989+ else
990+ {
991+ store::Item_t lValue;
992+ while (consumeNext(lValue, theChildren[1], aPlanState))
993+ {
994+ std::auto_ptr<store::IndexKey> k(new store::IndexKey());
995+ for (std::vector<store::Item_t>::const_iterator lIter = lKey.begin();
996+ lIter != lKey.end();
997+ ++lIter)
998+ {
999+ k->push_back(*lIter);
1000+ }
1001+
1002+ store::IndexKey* lKeyPtr = k.get();
1003+ if (!lIndex->insert(lKeyPtr, lValue))
1004+ {
1005+ // the index took the ownership over the key if the index
1006+ // did _not_ already contain an entry with the same key
1007+ k.release();
1008+ }
1009+ }
1010+ }
1011
1012 result = NULL;
1013
1014@@ -371,36 +484,28 @@
1015 store::Item_t lKeyItem;
1016 std::auto_ptr<store::PUL> lPul;
1017 store::IndexSpecification lSpec;
1018+ bool lPersistent;
1019
1020 PlanIteratorState* state;
1021 DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
1022
1023 consumeNext(lQName, theChildren[0].getp(), aPlanState);
1024
1025- lIndex = GENV_STORE.getMap(lQName);
1026-
1027- if (!lIndex)
1028- {
1029- throw XQUERY_EXCEPTION(
1030- zerr::ZDDY0023_INDEX_DOES_NOT_EXIST,
1031- ERROR_PARAMS( lQName->getStringValue() ),
1032- ERROR_LOC( loc )
1033- );
1034- }
1035+ lPersistent = getMap(lQName, loc, aPlanState.theLocalDynCtx, lIndex);
1036
1037 lSpec = lIndex->getSpecification();
1038
1039 if (lSpec.getNumColumns() != theChildren.size() - 1)
1040 {
1041- throw XQUERY_EXCEPTION(
1042+ RAISE_ERROR(
1043 zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS,
1044+ loc,
1045 ERROR_PARAMS(
1046 lQName->getStringValue(),
1047 "map",
1048 theChildren.size() - 1,
1049 lSpec.getNumColumns()
1050- ),
1051- ERROR_LOC( loc )
1052+ )
1053 );
1054 }
1055
1056@@ -414,15 +519,30 @@
1057 }
1058 }
1059
1060- lPul.reset(GENV_ITEMFACTORY->createPendingUpdateList());
1061- lPul->addRemoveFromHashMap(&loc, lQName, lKey);
1062+ if (lPersistent)
1063+ {
1064+ lPul.reset(GENV_ITEMFACTORY->createPendingUpdateList());
1065+ lPul->addRemoveFromHashMap(&loc, lQName, lKey);
1066
1067- apply_updates(
1068- aPlanState.theCompilerCB,
1069- aPlanState.theGlobalDynCtx,
1070- theSctx,
1071- lPul.get(),
1072- loc);
1073+ apply_updates(
1074+ aPlanState.theCompilerCB,
1075+ aPlanState.theGlobalDynCtx,
1076+ theSctx,
1077+ lPul.get(),
1078+ loc);
1079+ }
1080+ else
1081+ {
1082+ store::IndexKey k;
1083+ for (std::vector<store::Item_t>::const_iterator lIter = lKey.begin();
1084+ lIter != lKey.end();
1085+ ++lIter)
1086+ {
1087+ k.push_back(*lIter);
1088+ }
1089+ store::Item_t lValue;
1090+ lIndex->remove(&k, lValue, true);
1091+ }
1092
1093 result = NULL;
1094
1095@@ -454,16 +574,7 @@
1096
1097 consumeNext(lQName, theChildren[0].getp(), aPlanState);
1098
1099- lIndex = GENV_STORE.getMap(lQName);
1100-
1101- if (!lIndex)
1102- {
1103- throw XQUERY_EXCEPTION(
1104- zerr::ZDDY0023_INDEX_DOES_NOT_EXIST,
1105- ERROR_PARAMS( lQName->getStringValue() ),
1106- ERROR_LOC( loc )
1107- );
1108- }
1109+ getMap(lQName, loc, aPlanState.theLocalDynCtx, lIndex);
1110
1111 state->theIter = lIndex->keys();
1112
1113@@ -494,18 +605,23 @@
1114 static_context::ZORBA_STORE_DYNAMIC_UNORDERED_MAP_FN_NS,
1115 "", "attribute");
1116
1117- GENV_ITEMFACTORY->createQName(lValueAttrName,
1118- "", "", "value");
1119-
1120 lTypeName = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
1121
1122 GENV_ITEMFACTORY->createElementNode(
1123 lAttrElem, result, lAttrNodeName, lTypeName,
1124 true, false, theNSBindings, lBaseURI);
1125
1126- lTypeName = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
1127- GENV_ITEMFACTORY->createAttributeNode(
1128- lValueAttr, lAttrElem.getp(), lValueAttrName, lTypeName, (*lIter));
1129+ store::Item_t& lValue = (*lIter);
1130+ if (! lValue.isNull())
1131+ {
1132+ GENV_ITEMFACTORY->createQName(lValueAttrName,
1133+ "", "", "value");
1134+
1135+ lTypeName = lValue->getType();
1136+
1137+ GENV_ITEMFACTORY->createAttributeNode(
1138+ lValueAttr, lAttrElem.getp(), lValueAttrName, lTypeName, lValue);
1139+ }
1140 }
1141 STACK_PUSH(true, state);
1142 }
1143@@ -529,16 +645,7 @@
1144
1145 consumeNext(lQName, theChildren[0].getp(), aPlanState);
1146
1147- lIndex = GENV_STORE.getMap(lQName);
1148-
1149- if (!lIndex)
1150- {
1151- throw XQUERY_EXCEPTION(
1152- zerr::ZDDY0023_INDEX_DOES_NOT_EXIST,
1153- ERROR_PARAMS( lQName->getStringValue() ),
1154- ERROR_LOC( loc )
1155- );
1156- }
1157+ getMap(lQName, loc, aPlanState.theLocalDynCtx, lIndex);
1158
1159 GENV_ITEMFACTORY->createInteger(result, xs_integer(lIndex->size()));
1160
1161@@ -547,33 +654,36 @@
1162 STACK_END(state);
1163 }
1164
1165+
1166 /*******************************************************************************
1167
1168 ********************************************************************************/
1169 AvailableMapsIteratorState::~AvailableMapsIteratorState()
1170 {
1171- if ( nameItState != NULL )
1172+ if ( persistentMapNamesIter != NULL )
1173 {
1174- nameItState->close();
1175- nameItState = NULL;
1176+ persistentMapNamesIter->close();
1177+ persistentMapNamesIter = NULL;
1178 }
1179+ transientMapNames.clear();
1180 }
1181
1182
1183 void AvailableMapsIteratorState::init(PlanState& planState)
1184 {
1185 PlanIteratorState::init(planState);
1186- nameItState = NULL;
1187+ persistentMapNamesIter = NULL;
1188 }
1189
1190
1191 void AvailableMapsIteratorState::reset(PlanState& planState)
1192 {
1193 PlanIteratorState::reset(planState);
1194- if ( nameItState != NULL ) {
1195- nameItState->close();
1196- nameItState = NULL;
1197+ if ( persistentMapNamesIter != NULL ) {
1198+ persistentMapNamesIter->close();
1199+ persistentMapNamesIter = NULL;
1200 }
1201+ transientMapNames.clear();
1202 }
1203
1204
1205@@ -585,18 +695,54 @@
1206
1207 DEFAULT_STACK_INIT(AvailableMapsIteratorState, state, planState);
1208
1209- for ((state->nameItState = GENV_STORE.listMapNames())->open ();
1210- state->nameItState->next(nameItem); )
1211+ for ((state->persistentMapNamesIter = GENV_STORE.listMapNames())->open ();
1212+ state->persistentMapNamesIter->next(nameItem); )
1213 {
1214 result = nameItem;
1215 STACK_PUSH( true, state);
1216 }
1217
1218- state->nameItState->close();
1219+ state->persistentMapNamesIter->close();
1220+
1221+ planState.theLocalDynCtx->getMapNames(state->transientMapNames);
1222+
1223+ for (state->transientMapNamesIter = state->transientMapNames.begin();
1224+ state->transientMapNamesIter != state->transientMapNames.end();
1225+ ++state->transientMapNamesIter)
1226+ {
1227+ result = *state->transientMapNamesIter;
1228+ STACK_PUSH( true, state);
1229+ }
1230
1231 STACK_END (state);
1232 }
1233
1234
1235+/*******************************************************************************
1236+********************************************************************************/
1237+bool
1238+MapIsTransientIterator::nextImpl(
1239+ store::Item_t& result,
1240+ PlanState& aPlanState) const
1241+{
1242+ store::Item_t lQName;
1243+ store::Index* lIndex;
1244+ bool lPersistent;
1245+
1246+ PlanIteratorState* state;
1247+ DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
1248+
1249+ consumeNext(lQName, theChildren[0].getp(), aPlanState);
1250+
1251+ lPersistent = getMap(lQName, loc, aPlanState.theLocalDynCtx, lIndex);
1252+
1253+ GENV_ITEMFACTORY->createBoolean(result, !lPersistent);
1254+
1255+ STACK_PUSH(true, state);
1256+
1257+ STACK_END(state);
1258+}
1259+
1260+
1261 } // namespace zorba
1262 /* vim:set et sw=2 ts=2: */
1263
1264=== modified file 'src/runtime/store/pregenerated/maps.cpp'
1265--- src/runtime/store/pregenerated/maps.cpp 2012-06-18 10:06:47 +0000
1266+++ src/runtime/store/pregenerated/maps.cpp 2012-06-23 00:29:20 +0000
1267@@ -62,6 +62,34 @@
1268 // </MapCreateIterator>
1269
1270
1271+// <MapCreateTransientIterator>
1272+SERIALIZABLE_CLASS_VERSIONS(MapCreateTransientIterator)
1273+
1274+void MapCreateTransientIterator::serialize(::zorba::serialization::Archiver& ar)
1275+{
1276+ serialize_baseclass(ar,
1277+ (NaryBaseIterator<MapCreateTransientIterator, PlanIteratorState>*)this);
1278+}
1279+
1280+
1281+void MapCreateTransientIterator::accept(PlanIterVisitor& v) const
1282+{
1283+ v.beginVisit(*this);
1284+
1285+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
1286+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
1287+ for ( ; lIter != lEnd; ++lIter ){
1288+ (*lIter)->accept(v);
1289+ }
1290+
1291+ v.endVisit(*this);
1292+}
1293+
1294+MapCreateTransientIterator::~MapCreateTransientIterator() {}
1295+
1296+// </MapCreateTransientIterator>
1297+
1298+
1299 // <MapDestroyIterator>
1300 SERIALIZABLE_CLASS_VERSIONS(MapDestroyIterator)
1301
1302@@ -286,6 +314,34 @@
1303 // </AvailableMapsIterator>
1304
1305
1306+// <MapIsTransientIterator>
1307+SERIALIZABLE_CLASS_VERSIONS(MapIsTransientIterator)
1308+
1309+void MapIsTransientIterator::serialize(::zorba::serialization::Archiver& ar)
1310+{
1311+ serialize_baseclass(ar,
1312+ (NaryBaseIterator<MapIsTransientIterator, PlanIteratorState>*)this);
1313+}
1314+
1315+
1316+void MapIsTransientIterator::accept(PlanIterVisitor& v) const
1317+{
1318+ v.beginVisit(*this);
1319+
1320+ std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
1321+ std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
1322+ for ( ; lIter != lEnd; ++lIter ){
1323+ (*lIter)->accept(v);
1324+ }
1325+
1326+ v.endVisit(*this);
1327+}
1328+
1329+MapIsTransientIterator::~MapIsTransientIterator() {}
1330+
1331+// </MapIsTransientIterator>
1332+
1333+
1334
1335 }
1336
1337
1338=== modified file 'src/runtime/store/pregenerated/maps.h'
1339--- src/runtime/store/pregenerated/maps.h 2012-06-18 10:06:47 +0000
1340+++ src/runtime/store/pregenerated/maps.h 2012-06-23 00:29:20 +0000
1341@@ -29,6 +29,7 @@
1342
1343
1344 #include "runtime/base/narybase.h"
1345+#include <vector>
1346 #include "store/api/index.h"
1347
1348
1349@@ -70,6 +71,37 @@
1350 *
1351 * Author: Matthias Brantner
1352 */
1353+class MapCreateTransientIterator : public NaryBaseIterator<MapCreateTransientIterator, PlanIteratorState>
1354+{
1355+public:
1356+ SERIALIZABLE_CLASS(MapCreateTransientIterator);
1357+
1358+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(MapCreateTransientIterator,
1359+ NaryBaseIterator<MapCreateTransientIterator, PlanIteratorState>);
1360+
1361+ void serialize( ::zorba::serialization::Archiver& ar);
1362+
1363+ MapCreateTransientIterator(
1364+ static_context* sctx,
1365+ const QueryLoc& loc,
1366+ std::vector<PlanIter_t>& children)
1367+ :
1368+ NaryBaseIterator<MapCreateTransientIterator, PlanIteratorState>(sctx, loc, children)
1369+ {}
1370+
1371+ virtual ~MapCreateTransientIterator();
1372+
1373+ void accept(PlanIterVisitor& v) const;
1374+
1375+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
1376+};
1377+
1378+
1379+/**
1380+ *
1381+ *
1382+ * Author: Matthias Brantner
1383+ */
1384 class MapDestroyIterator : public NaryBaseIterator<MapDestroyIterator, PlanIteratorState>
1385 {
1386 public:
1387@@ -289,7 +321,9 @@
1388 class AvailableMapsIteratorState : public PlanIteratorState
1389 {
1390 public:
1391- store::Iterator_t nameItState; //the current iterator
1392+ store::Iterator_t persistentMapNamesIter; //the current iterator
1393+ std::vector<store::Item_t> transientMapNames; //all the transient map names
1394+ std::vector<store::Item_t>::const_iterator transientMapNamesIter; //the current iterator
1395
1396 AvailableMapsIteratorState();
1397
1398@@ -325,6 +359,37 @@
1399 };
1400
1401
1402+/**
1403+ *
1404+ *
1405+ * Author: Matthias Brantner
1406+ */
1407+class MapIsTransientIterator : public NaryBaseIterator<MapIsTransientIterator, PlanIteratorState>
1408+{
1409+public:
1410+ SERIALIZABLE_CLASS(MapIsTransientIterator);
1411+
1412+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(MapIsTransientIterator,
1413+ NaryBaseIterator<MapIsTransientIterator, PlanIteratorState>);
1414+
1415+ void serialize( ::zorba::serialization::Archiver& ar);
1416+
1417+ MapIsTransientIterator(
1418+ static_context* sctx,
1419+ const QueryLoc& loc,
1420+ std::vector<PlanIter_t>& children)
1421+ :
1422+ NaryBaseIterator<MapIsTransientIterator, PlanIteratorState>(sctx, loc, children)
1423+ {}
1424+
1425+ virtual ~MapIsTransientIterator();
1426+
1427+ void accept(PlanIterVisitor& v) const;
1428+
1429+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
1430+};
1431+
1432+
1433 }
1434 #endif
1435 /*
1436
1437=== modified file 'src/runtime/visitors/pregenerated/planiter_visitor.h'
1438--- src/runtime/visitors/pregenerated/planiter_visitor.h 2012-06-18 10:06:47 +0000
1439+++ src/runtime/visitors/pregenerated/planiter_visitor.h 2012-06-23 00:29:20 +0000
1440@@ -621,6 +621,8 @@
1441
1442 class MapCreateIterator;
1443
1444+ class MapCreateTransientIterator;
1445+
1446 class MapDestroyIterator;
1447
1448 class MapGetIterator;
1449@@ -635,6 +637,8 @@
1450
1451 class AvailableMapsIterator;
1452
1453+ class MapIsTransientIterator;
1454+
1455 class CodepointsToStringIterator;
1456
1457 class StringToCodepointsIterator;
1458@@ -1580,6 +1584,9 @@
1459 virtual void beginVisit ( const MapCreateIterator& ) = 0;
1460 virtual void endVisit ( const MapCreateIterator& ) = 0;
1461
1462+ virtual void beginVisit ( const MapCreateTransientIterator& ) = 0;
1463+ virtual void endVisit ( const MapCreateTransientIterator& ) = 0;
1464+
1465 virtual void beginVisit ( const MapDestroyIterator& ) = 0;
1466 virtual void endVisit ( const MapDestroyIterator& ) = 0;
1467
1468@@ -1601,6 +1608,9 @@
1469 virtual void beginVisit ( const AvailableMapsIterator& ) = 0;
1470 virtual void endVisit ( const AvailableMapsIterator& ) = 0;
1471
1472+ virtual void beginVisit ( const MapIsTransientIterator& ) = 0;
1473+ virtual void endVisit ( const MapIsTransientIterator& ) = 0;
1474+
1475 virtual void beginVisit ( const CodepointsToStringIterator& ) = 0;
1476 virtual void endVisit ( const CodepointsToStringIterator& ) = 0;
1477
1478
1479=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.cpp'
1480--- src/runtime/visitors/pregenerated/printer_visitor.cpp 2012-06-18 10:06:47 +0000
1481+++ src/runtime/visitors/pregenerated/printer_visitor.cpp 2012-06-23 00:29:20 +0000
1482@@ -4064,6 +4064,20 @@
1483 // </MapCreateIterator>
1484
1485
1486+// <MapCreateTransientIterator>
1487+void PrinterVisitor::beginVisit ( const MapCreateTransientIterator& a) {
1488+ thePrinter.startBeginVisit("MapCreateTransientIterator", ++theId);
1489+ printCommons( &a, theId );
1490+ thePrinter.endBeginVisit( theId );
1491+}
1492+
1493+void PrinterVisitor::endVisit ( const MapCreateTransientIterator& ) {
1494+ thePrinter.startEndVisit();
1495+ thePrinter.endEndVisit();
1496+}
1497+// </MapCreateTransientIterator>
1498+
1499+
1500 // <MapDestroyIterator>
1501 void PrinterVisitor::beginVisit ( const MapDestroyIterator& a) {
1502 thePrinter.startBeginVisit("MapDestroyIterator", ++theId);
1503@@ -4162,6 +4176,20 @@
1504 // </AvailableMapsIterator>
1505
1506
1507+// <MapIsTransientIterator>
1508+void PrinterVisitor::beginVisit ( const MapIsTransientIterator& a) {
1509+ thePrinter.startBeginVisit("MapIsTransientIterator", ++theId);
1510+ printCommons( &a, theId );
1511+ thePrinter.endBeginVisit( theId );
1512+}
1513+
1514+void PrinterVisitor::endVisit ( const MapIsTransientIterator& ) {
1515+ thePrinter.startEndVisit();
1516+ thePrinter.endEndVisit();
1517+}
1518+// </MapIsTransientIterator>
1519+
1520+
1521 // <CodepointsToStringIterator>
1522 void PrinterVisitor::beginVisit ( const CodepointsToStringIterator& a) {
1523 thePrinter.startBeginVisit("CodepointsToStringIterator", ++theId);
1524
1525=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.h'
1526--- src/runtime/visitors/pregenerated/printer_visitor.h 2012-06-18 10:06:47 +0000
1527+++ src/runtime/visitors/pregenerated/printer_visitor.h 2012-06-23 00:29:20 +0000
1528@@ -949,6 +949,9 @@
1529 void beginVisit( const MapCreateIterator& );
1530 void endVisit ( const MapCreateIterator& );
1531
1532+ void beginVisit( const MapCreateTransientIterator& );
1533+ void endVisit ( const MapCreateTransientIterator& );
1534+
1535 void beginVisit( const MapDestroyIterator& );
1536 void endVisit ( const MapDestroyIterator& );
1537
1538@@ -970,6 +973,9 @@
1539 void beginVisit( const AvailableMapsIterator& );
1540 void endVisit ( const AvailableMapsIterator& );
1541
1542+ void beginVisit( const MapIsTransientIterator& );
1543+ void endVisit ( const MapIsTransientIterator& );
1544+
1545 void beginVisit( const CodepointsToStringIterator& );
1546 void endVisit ( const CodepointsToStringIterator& );
1547
1548
1549=== modified file 'src/store/api/index.h'
1550--- src/store/api/index.h 2012-06-18 10:06:47 +0000
1551+++ src/store/api/index.h 2012-06-23 00:29:20 +0000
1552@@ -427,6 +427,11 @@
1553 * a general index
1554 */
1555 virtual bool insert(store::IndexKey*& key, store::Item_t& item) = 0;
1556+
1557+ virtual bool remove(
1558+ const store::IndexKey* key,
1559+ const store::Item_t& item,
1560+ bool all = false) = 0;
1561 };
1562
1563
1564
1565=== modified file 'src/store/api/store.h'
1566--- src/store/api/store.h 2012-06-18 10:06:47 +0000
1567+++ src/store/api/store.h 2012-06-23 00:29:20 +0000
1568@@ -320,6 +320,10 @@
1569
1570 /* --------------------------- Map Management ------------------------------*/
1571
1572+ virtual Index_t createMap(
1573+ const Item_t& qname,
1574+ const IndexSpecification& spec) = 0;
1575+
1576 virtual Index* getMap(const Item* aQName) const = 0;
1577
1578 virtual Iterator_t listMapNames() = 0;
1579
1580=== modified file 'src/store/naive/pul_primitives.cpp'
1581--- src/store/naive/pul_primitives.cpp 2012-06-18 10:06:47 +0000
1582+++ src/store/naive/pul_primitives.cpp 2012-06-23 00:29:20 +0000
1583@@ -1734,7 +1734,7 @@
1584 lSpec.theTimezone = theTimezone;
1585
1586
1587- GET_STORE().createHashMap(theQName, lSpec);
1588+ GET_STORE().createMap(theQName, lSpec);
1589 theIsApplied = true;
1590 }
1591
1592@@ -1743,7 +1743,7 @@
1593 {
1594 if (theIsApplied)
1595 {
1596- GET_STORE().destroyHashMap(theQName);
1597+ GET_STORE().destroyMap(theQName);
1598 }
1599 }
1600
1601@@ -1763,7 +1763,7 @@
1602
1603 void UpdDestroyHashMap::apply()
1604 {
1605- theMap = GET_STORE().destroyHashMap(theQName);
1606+ theMap = GET_STORE().destroyMap(theQName);
1607 theIsApplied = true;
1608 }
1609
1610@@ -1772,7 +1772,7 @@
1611 {
1612 if (theIsApplied)
1613 {
1614- GET_STORE().addHashMap(theMap);
1615+ GET_STORE().addMap(theMap);
1616 }
1617 }
1618
1619@@ -1796,7 +1796,7 @@
1620
1621 void UpdInsertIntoHashMap::apply()
1622 {
1623- store::Index_t lMap = GET_STORE().getHashMap(theQName);
1624+ store::Index_t lMap = GET_STORE().getMap(theQName);
1625
1626 if (!lMap)
1627 {
1628@@ -1809,7 +1809,6 @@
1629 theValue->open();
1630 store::Item_t lValue;
1631
1632- store::IndexKey lKeyPtr;
1633 while (theValue->next(lValue))
1634 {
1635 std::auto_ptr<store::IndexKey> lKey(new store::IndexKey());
1636@@ -1853,7 +1852,7 @@
1637
1638 void UpdRemoveFromHashMap::apply()
1639 {
1640- store::Index_t lMap = GET_STORE().getHashMap(theQName);
1641+ store::Index_t lMap = GET_STORE().getMap(theQName);
1642
1643 if (!lMap)
1644 {
1645
1646=== modified file 'src/store/naive/simple_index_general.cpp'
1647--- src/store/naive/simple_index_general.cpp 2012-06-18 10:06:47 +0000
1648+++ src/store/naive/simple_index_general.cpp 2012-06-23 00:29:20 +0000
1649@@ -747,7 +747,7 @@
1650 *******************************************************************************/
1651 bool GeneralHashIndex::remove(
1652 const store::Item_t& key,
1653- store::Item_t& item,
1654+ const store::Item_t& item,
1655 bool all)
1656 {
1657 assert(false);
1658@@ -922,7 +922,7 @@
1659 *******************************************************************************/
1660 bool GeneralTreeIndex::remove(
1661 const store::Item_t& key,
1662- store::Item_t& item,
1663+ const store::Item_t& item,
1664 bool all)
1665 {
1666 return true;
1667
1668=== modified file 'src/store/naive/simple_index_general.h'
1669--- src/store/naive/simple_index_general.h 2012-06-18 10:06:47 +0000
1670+++ src/store/naive/simple_index_general.h 2012-06-23 00:29:20 +0000
1671@@ -176,7 +176,12 @@
1672
1673 bool insert(store::IndexKey*& key, store::Item_t& value);
1674
1675- virtual bool remove(const store::Item_t& key, store::Item_t& item, bool all) = 0;
1676+ virtual bool remove(const store::Item_t& key, const store::Item_t& item, bool all) = 0;
1677+
1678+ virtual bool remove(
1679+ const store::IndexKey* key,
1680+ const store::Item_t& item,
1681+ bool all = false) = 0;
1682 };
1683
1684
1685@@ -237,7 +242,16 @@
1686
1687 Index::KeyIterator_t keys() const;
1688
1689- bool remove(const store::Item_t& key, store::Item_t& item, bool);
1690+ bool remove(const store::Item_t& key, const store::Item_t& item, bool);
1691+
1692+ bool remove(
1693+ const store::IndexKey* key,
1694+ const store::Item_t& item,
1695+ bool all = false)
1696+ {
1697+ assert(key->size() == 1);
1698+ return remove(((*key)[0]), item, all);
1699+ }
1700
1701 void clear();
1702 };
1703@@ -292,7 +306,16 @@
1704
1705 Index::KeyIterator_t keys() const;
1706
1707- bool remove(const store::Item_t& key, store::Item_t& item, bool all);
1708+ bool remove(const store::Item_t& key, const store::Item_t& item, bool all);
1709+
1710+ bool remove(
1711+ const store::IndexKey* key,
1712+ const store::Item_t& item,
1713+ bool all = false)
1714+ {
1715+ assert(key->size() == 1);
1716+ return remove(((*key)[0]), item, all);
1717+ }
1718
1719 void clear();
1720 };
1721
1722=== modified file 'src/store/naive/store.cpp'
1723--- src/store/naive/store.cpp 2012-06-22 08:19:01 +0000
1724+++ src/store/naive/store.cpp 2012-06-23 00:29:20 +0000
1725@@ -889,7 +889,7 @@
1726
1727 ********************************************************************************/
1728 store::Index_t
1729-Store::createHashMap(
1730+Store::createMap(
1731 const store::Item_t& aQName,
1732 const store::IndexSpecification& aSpec)
1733 {
1734@@ -905,7 +905,7 @@
1735
1736 lIndex = new ValueHashIndex(aQName, aSpec);
1737
1738- addHashMap(lIndex);
1739+ if (!aSpec.theIsTemp) addMap(lIndex);
1740
1741 return lIndex;
1742 }
1743@@ -915,7 +915,7 @@
1744
1745 ********************************************************************************/
1746 store::Index_t
1747-Store::destroyHashMap(const store::Item_t& aQName)
1748+Store::destroyMap(const store::Item_t& aQName)
1749 {
1750 store::Index_t lIndex;
1751 if (!theHashMaps.get(aQName.getp(), lIndex))
1752@@ -950,7 +950,7 @@
1753
1754 ********************************************************************************/
1755 store::Index_t
1756-Store::getHashMap(const store::Item_t& aQName) const
1757+Store::getMap(const store::Item_t& aQName) const
1758 {
1759 store::Index_t lIndex;
1760 if (const_cast<IndexSet*>(&theHashMaps)->get(aQName.getp(), lIndex))
1761@@ -968,7 +968,7 @@
1762
1763 ********************************************************************************/
1764 void
1765-Store::addHashMap(const store::Index_t& aIndex)
1766+Store::addMap(const store::Index_t& aIndex)
1767 {
1768 store::Item* lName = aIndex->getName();
1769 store::Index_t lIndex = aIndex;
1770
1771=== modified file 'src/store/naive/store.h'
1772--- src/store/naive/store.h 2012-06-18 10:06:47 +0000
1773+++ src/store/naive/store.h 2012-06-23 00:29:20 +0000
1774@@ -342,17 +342,17 @@
1775
1776 /*------------------------------------- Maps ---------------------------------*/
1777 public:
1778- virtual store::Index_t createHashMap(
1779+ virtual store::Index_t createMap(
1780 const store::Item_t& aQName,
1781 const store::IndexSpecification& aSpec);
1782
1783- virtual store::Index_t destroyHashMap(const store::Item_t& aQName);
1784+ virtual store::Index_t destroyMap(const store::Item_t& aQName);
1785
1786 virtual store::Index* getMap(const store::Item* aQName) const;
1787
1788- virtual store::Index_t getHashMap(const store::Item_t& aQName) const;
1789+ virtual store::Index_t getMap(const store::Item_t& aQName) const;
1790
1791- virtual void addHashMap(const store::Index_t& aMap);
1792+ virtual void addMap(const store::Index_t& aMap);
1793
1794 virtual store::Iterator_t listMapNames();
1795
1796
1797=== added file 'test/rbkt/ExpQueryResults/zorba/store/unordered-map/map7.xml.res'
1798--- test/rbkt/ExpQueryResults/zorba/store/unordered-map/map7.xml.res 1970-01-01 00:00:00 +0000
1799+++ test/rbkt/ExpQueryResults/zorba/store/unordered-map/map7.xml.res 2012-06-23 00:29:20 +0000
1800@@ -0,0 +1,1 @@
1801+true true 1 key1 value1 true false 3 true true 5 key5 value5 false true key2 false true key4 false false
1802
1803=== added file 'test/rbkt/ExpQueryResults/zorba/store/unordered-map/transient-map0.xml.res'
1804--- test/rbkt/ExpQueryResults/zorba/store/unordered-map/transient-map0.xml.res 1970-01-01 00:00:00 +0000
1805+++ test/rbkt/ExpQueryResults/zorba/store/unordered-map/transient-map0.xml.res 2012-06-23 00:29:20 +0000
1806@@ -0,0 +1,1 @@
1807+<avail>first</avail><contains>value5</contains><contains></contains><avail></avail>
1808\ No newline at end of file
1809
1810=== added file 'test/rbkt/Queries/zorba/store/unordered-map/map7.xq'
1811--- test/rbkt/Queries/zorba/store/unordered-map/map7.xq 1970-01-01 00:00:00 +0000
1812+++ test/rbkt/Queries/zorba/store/unordered-map/map7.xq 2012-06-23 00:29:20 +0000
1813@@ -0,0 +1,22 @@
1814+import module namespace map = "http://www.zorba-xquery.com/modules/store/data-structures/unordered-map";
1815+
1816+variable $name := fn:QName("http://www.zorba-xquery.com/map", "first");
1817+variable $xs-integer := fn:QName("http://www.w3.org/2001/XMLSchema", "xs:integer");
1818+variable $xs-string := fn:QName("http://www.w3.org/2001/XMLSchema", "xs:string");
1819+
1820+map:create($name, $xs-integer, $xs-string);
1821+
1822+for $i in 1 to 6
1823+let $value := concat("value", $i),
1824+ $key1 := if ($i mod 2 ne 0) then $i else (),
1825+ $key2 := if ($i mod 3 ne 0) then concat("key", $i) else ()
1826+return
1827+ map:insert($name, $value, $key1, $key2);
1828+
1829+for $k in map:keys($name)
1830+let $key1 := data($k/map:attribute[1]/@value),
1831+ $key2 := data($k/map:attribute[2]/@value)
1832+order by $key1, $key2
1833+return
1834+ ($key1 instance of xs:integer, $key2 instance of xs:string,
1835+ $key1, $key2, map:get($name, $key1, $key2))
1836
1837=== added file 'test/rbkt/Queries/zorba/store/unordered-map/transient-map0.xq'
1838--- test/rbkt/Queries/zorba/store/unordered-map/transient-map0.xq 1970-01-01 00:00:00 +0000
1839+++ test/rbkt/Queries/zorba/store/unordered-map/transient-map0.xq 2012-06-23 00:29:20 +0000
1840@@ -0,0 +1,27 @@
1841+import module namespace map = "http://www.zorba-xquery.com/modules/store/data-structures/unordered-map";
1842+
1843+
1844+let $name := fn:QName("http://www.zorba-xquery.com/map", "first")
1845+let $type := fn:QName("http://www.w3.org/2001/XMLSchema", "xs:integer")
1846+return
1847+ {
1848+ map:create-transient($name, $type);
1849+
1850+ (
1851+ for $i in 1 to 1000
1852+ return map:insert($name, concat("value", $i), $i)
1853+ );
1854+
1855+ variable $res := <avail>{ map:available-maps() }</avail>;
1856+
1857+ $res := ($res, <contains>{ map:get($name, 5) }</contains>);
1858+
1859+ map:remove($name, 5);
1860+
1861+ $res := ($res, <contains>{ map:get($name, 5) }</contains>);
1862+
1863+ map:delete($name);
1864+
1865+ ($res, <avail>{ map:available-maps() }</avail>)
1866+ }
1867+

Subscribers

People subscribed via source and target branches