~paul-lucas/zorba/bug-932374

« back to all changes in this revision

Viewing changes to src/store/naive/simple_lazy_temp_seq.cpp

  • Committer: Paul J. Lucas
  • Date: 2012-09-21 20:26:47 UTC
  • mfrom: (10819.2.235 zorba)
  • Revision ID: paul@lucasmail.org-20120921202647-fy9n4jduhrnljrnb
MergeĀ fromĀ trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
/*******************************************************************************
34
34
 
35
35
********************************************************************************/
36
 
SimpleLazyTempSeq::SimpleLazyTempSeq(const store::Iterator_t& aIter)
 
36
SimpleLazyTempSeq::SimpleLazyTempSeq(const store::Iterator_t& iter)
37
37
{
38
 
  init(aIter);
 
38
  init(iter);
39
39
}
40
40
 
41
41
 
44
44
********************************************************************************/
45
45
SimpleLazyTempSeq::~SimpleLazyTempSeq()
46
46
{
 
47
  clear();
47
48
}
48
49
 
49
50
 
50
51
/*******************************************************************************
51
52
 
52
53
********************************************************************************/
53
 
void SimpleLazyTempSeq::init(const store::Iterator_t& aIter)
 
54
void SimpleLazyTempSeq::clear()
54
55
{
55
 
  theIterator = aIter;
56
 
  theMatFinished = false;
57
 
  thePurgedUpTo = 0;
 
56
  std::vector<store::Item*>::iterator ite = theItems.begin();
 
57
  std::vector<store::Item*>::iterator end = theItems.end();
 
58
  for (; ite != end; ++ite)
 
59
  {
 
60
    (*ite)->removeReference();
 
61
  }
 
62
 
58
63
  theItems.clear();
59
64
}
60
65
 
61
66
 
62
67
/*******************************************************************************
63
 
 
64
 
********************************************************************************/
65
 
void SimpleLazyTempSeq::append(const store::Iterator_t& iter)
66
 
{
67
 
  while (!theMatFinished)
68
 
  {
69
 
    matNextItem();
70
 
  }
71
 
 
72
 
  theMatFinished = false;
73
 
  theIterator = iter;
74
 
}
75
 
 
76
 
 
77
 
/*******************************************************************************
78
 
 
79
 
********************************************************************************/
80
 
void SimpleLazyTempSeq::purge()
81
 
{
82
 
  //Not supported
83
 
}
84
 
 
85
 
 
86
 
/*******************************************************************************
87
 
 
88
 
********************************************************************************/
89
 
void SimpleLazyTempSeq::purgeUpTo(xs_integer upTo)
90
 
{
91
 
  xs_long lUpTo;
92
 
  try 
93
 
  {
94
 
    lUpTo = to_xs_long(upTo);
95
 
  }
96
 
  catch (std::range_error& e)
97
 
  {
98
 
    throw ZORBA_EXCEPTION(zerr::ZSTR0060_RANGE_EXCEPTION,
99
 
    ERROR_PARAMS(BUILD_STRING("sequence too big (" << e.what() << ")")));
100
 
  }
101
 
 
102
 
  ZORBA_ASSERT(lUpTo >= thePurgedUpTo);
103
 
  ZORBA_ASSERT(lUpTo - thePurgedUpTo <= theItems.size());
104
 
 
105
 
  theItems.erase(theItems.begin(), (theItems.begin() + (lUpTo - thePurgedUpTo)));
106
 
  thePurgedUpTo = lUpTo;
 
68
  Get the next item (if any) from the input iterator and put it at the end of 
 
69
  the queue.  
 
70
********************************************************************************/
 
71
void SimpleLazyTempSeq::matNextItem() 
 
72
{
 
73
  store::Item_t item;
 
74
 
 
75
  if (! theIterator->next(item)) 
 
76
  {
 
77
    theMatFinished = true;
 
78
  }
 
79
  else
 
80
  {
 
81
    theItems.push_back(item.release());
 
82
  }
107
83
}
108
84
 
109
85
 
134
110
/*******************************************************************************
135
111
 
136
112
********************************************************************************/
 
113
xs_integer SimpleLazyTempSeq::getSize() const
 
114
{
 
115
  ZORBA_ASSERT(false);
 
116
  return xs_integer(thePurgedUpTo + theItems.size());
 
117
}
 
118
 
 
119
 
 
120
/*******************************************************************************
 
121
 
 
122
********************************************************************************/
 
123
void SimpleLazyTempSeq::init(const store::Iterator_t& iter)
 
124
{
 
125
  theIterator = iter;
 
126
 
 
127
  theMatFinished = false;
 
128
  thePurgedUpTo = 0;
 
129
 
 
130
  clear();
 
131
}
 
132
 
 
133
 
 
134
/*******************************************************************************
 
135
 
 
136
********************************************************************************/
 
137
void SimpleLazyTempSeq::append(const store::Iterator_t& iter)
 
138
{
 
139
  while (!theMatFinished)
 
140
  {
 
141
    matNextItem();
 
142
  }
 
143
 
 
144
  theMatFinished = false;
 
145
  theIterator = iter;
 
146
}
 
147
 
 
148
 
 
149
/*******************************************************************************
 
150
 
 
151
********************************************************************************/
 
152
void SimpleLazyTempSeq::purge()
 
153
{
 
154
  theIterator = NULL;
 
155
 
 
156
  theMatFinished = false;
 
157
  thePurgedUpTo = 0;
 
158
 
 
159
  clear();
 
160
}
 
161
 
 
162
 
 
163
/*******************************************************************************
 
164
 
 
165
********************************************************************************/
 
166
void SimpleLazyTempSeq::purgeUpTo(xs_integer position)
 
167
{
 
168
  xs_long pos;
 
169
  try 
 
170
  {
 
171
    pos = to_xs_long(position);
 
172
  }
 
173
  catch (std::range_error& e)
 
174
  {
 
175
    throw ZORBA_EXCEPTION(zerr::ZSTR0060_RANGE_EXCEPTION,
 
176
    ERROR_PARAMS(BUILD_STRING("sequence too big (" << e.what() << ")")));
 
177
  }
 
178
 
 
179
  ZORBA_ASSERT(pos >= thePurgedUpTo);
 
180
  ZORBA_ASSERT(pos - thePurgedUpTo <= theItems.size());
 
181
 
 
182
  std::vector<store::Item*>::iterator ite = theItems.begin();
 
183
  std::vector<store::Item*>::iterator end = theItems.begin() + (pos - thePurgedUpTo);
 
184
  for (; ite != end; ++ite)
 
185
  {
 
186
    (*ite)->removeReference();
 
187
  }
 
188
 
 
189
  theItems.erase(theItems.begin(), end);
 
190
 
 
191
  thePurgedUpTo = pos;
 
192
}
 
193
 
 
194
 
 
195
/*******************************************************************************
 
196
 
 
197
********************************************************************************/
137
198
void SimpleLazyTempSeq::getItem(xs_integer position, store::Item_t& result)
138
199
{
139
 
  xs_long lPos;
 
200
  xs_long pos;
140
201
  try 
141
202
  {
142
 
    lPos = to_xs_long(position);
 
203
    pos = to_xs_long(position);
143
204
  }
144
205
  catch (std::range_error& e)
145
206
  {
147
208
    ERROR_PARAMS(BUILD_STRING("access out of bounds " << e.what() << ")")));
148
209
  }
149
210
 
150
 
  if (this->containsItem(position)) 
151
 
  {
152
 
    result = theItems[lPos - thePurgedUpTo - 1];
 
211
  ZORBA_ASSERT(pos > thePurgedUpTo);
 
212
 
 
213
  xs_long numItemsToBuffer = pos - thePurgedUpTo;
 
214
 
 
215
  while (!theMatFinished && theItems.size() <  numItemsToBuffer) 
 
216
  {
 
217
    matNextItem();
 
218
  }
 
219
 
 
220
  if (theItems.size() >= numItemsToBuffer)
 
221
  {
 
222
    result = theItems[pos - thePurgedUpTo - 1];
153
223
  }
154
224
  else 
155
225
  {
180
250
********************************************************************************/
181
251
inline bool SimpleLazyTempSeq::containsItem(xs_integer position) 
182
252
{
183
 
  xs_long lPos;
 
253
  xs_long pos;
184
254
  try 
185
255
  {
186
 
    lPos = to_xs_long(position);
 
256
    pos = to_xs_long(position);
187
257
  }
188
258
  catch (std::range_error& e)
189
259
  {
191
261
    ERROR_PARAMS(BUILD_STRING("access out of bounds " << e.what() << ")")));
192
262
  }
193
263
 
194
 
  assert(lPos > thePurgedUpTo);
 
264
  ZORBA_ASSERT(pos > thePurgedUpTo);
195
265
 
196
 
  xs_long numItemsToBuffer = lPos - thePurgedUpTo;
 
266
  xs_long numItemsToBuffer = pos - thePurgedUpTo;
197
267
 
198
268
  while (!theMatFinished && theItems.size() <  numItemsToBuffer) 
199
269
  {
205
275
 
206
276
 
207
277
/*******************************************************************************
208
 
  Get the next item (if any) from the input iterator and put it at the end of 
209
 
  the queue.  
210
 
********************************************************************************/
211
 
void SimpleLazyTempSeq::matNextItem() 
212
 
{
213
 
  theItems.push_back(NULL);
214
 
 
215
 
  store::Item_t& lLocation = theItems.back();
216
 
 
217
 
  if (theIterator->next(lLocation)) 
218
 
  {
219
 
    if (theCopy && lLocation->isNode()) 
220
 
    {
221
 
      store::CopyMode lCopyMode;
222
 
      lLocation = lLocation->copy(NULL, lCopyMode);
223
 
    }
224
 
  }
225
 
  else 
226
 
  {
227
 
    // We do not want to have an empty item materialized.
228
 
    theItems.pop_back();
229
 
    theMatFinished = true;
230
 
    theIterator->close();
231
 
  }
232
 
}
233
 
 
234
 
 
235
 
/*******************************************************************************
236
 
 
237
 
********************************************************************************/
238
 
xs_integer SimpleLazyTempSeq::getSize() const
239
 
{
240
 
  ZORBA_ASSERT(false);
241
 
  return xs_integer(0);
242
 
}
243
 
 
244
 
 
245
 
/*******************************************************************************
246
278
  Reads the whole Sequence from beginning to end; it is allowed to have several
247
279
  concurrent iterators on the same TempSeq.
248
280
 
250
282
********************************************************************************/
251
283
store::Iterator_t SimpleLazyTempSeq::getIterator() const
252
284
{
253
 
  return new SimpleLazyTempSeqIter(this, xs_integer(1), xs_integer(std::numeric_limits<long>::max()));
 
285
  return new SimpleLazyTempSeqIter(this,
 
286
                                   xs_integer(1),
 
287
                                   xs_integer(std::numeric_limits<long>::max()));
254
288
}
255
289
 
256
290
 
 
291
/////////////////////////////////////////////////////////////////////////////////
 
292
//                                                                             //
 
293
//  SimpleLazyTempSeqIter                                                      //
 
294
//                                                                             //
 
295
/////////////////////////////////////////////////////////////////////////////////
 
296
 
 
297
 
257
298
/*******************************************************************************
258
 
  Returns an iterator which reads just a part of the underlying TempSeq
259
299
 
260
 
  @param startPos The first item which the iterator returns
261
 
  @param endPos The last item which the iterator returns
262
 
  @return Iterator
263
300
********************************************************************************/
264
 
store::Iterator_t SimpleLazyTempSeq::getIterator(
265
 
    xs_integer startPos,
266
 
    xs_integer endPos,
267
 
    bool streaming) const
 
301
SimpleLazyTempSeqIter::SimpleLazyTempSeqIter()
 
302
  :
 
303
  theCurPos(0),
 
304
  theStartPos(0),
 
305
  theEndPos(0)
268
306
{
269
 
  return new SimpleLazyTempSeqIter(this, startPos, endPos);
270
307
}
271
308
 
272
309
 
274
311
 
275
312
********************************************************************************/
276
313
SimpleLazyTempSeqIter::SimpleLazyTempSeqIter(
277
 
    const SimpleLazyTempSeq* aTempSeq,
278
 
    xs_integer aStartPos,
279
 
    xs_integer aEndPos)
 
314
    const SimpleLazyTempSeq* tempSeq,
 
315
    xs_integer startPos,
 
316
    xs_integer endPos)
280
317
  :
281
 
  theTempSeq(const_cast<SimpleLazyTempSeq*>(aTempSeq))
 
318
  theTempSeq(const_cast<SimpleLazyTempSeq*>(tempSeq))
282
319
{
283
320
  try 
284
321
  {
285
 
    theCurPos = to_xs_long(aStartPos) - 1;
286
 
    theStartPos = to_xs_long(aStartPos);
287
 
    theEndPos = to_xs_long(aEndPos);
 
322
    theStartPos = to_xs_long(startPos);
 
323
    theEndPos = to_xs_long(endPos);
 
324
    theCurPos = theStartPos - 1;
288
325
  }
289
326
  catch (std::range_error& e)
290
327
  {
294
331
}
295
332
 
296
333
 
 
334
/*******************************************************************************
 
335
 
 
336
********************************************************************************/
297
337
SimpleLazyTempSeqIter::~SimpleLazyTempSeqIter()
298
338
{
299
339
}
300
340
 
301
341
 
 
342
/*******************************************************************************
 
343
 
 
344
********************************************************************************/
 
345
void SimpleLazyTempSeqIter::init(const store::TempSeq_t& seq)
 
346
{
 
347
  ZORBA_ASSERT(false);
 
348
}
 
349
 
 
350
 
 
351
/*******************************************************************************
 
352
 
 
353
********************************************************************************/
 
354
void SimpleLazyTempSeqIter::init(
 
355
    const store::TempSeq_t& seq,
 
356
    xs_integer startPos,
 
357
    xs_integer endPos)
 
358
{
 
359
  assert(seq->isLazy());
 
360
 
 
361
  theTempSeq = static_cast<SimpleLazyTempSeq*>(seq.getp());
 
362
 
 
363
  try 
 
364
  {
 
365
    theStartPos = to_xs_long(startPos);
 
366
    theEndPos = to_xs_long(endPos);
 
367
    theCurPos = theStartPos - 1;
 
368
  }
 
369
  catch (std::range_error& e)
 
370
  {
 
371
    RAISE_ERROR_NO_LOC(zerr::ZSTR0060_RANGE_EXCEPTION,
 
372
    ERROR_PARAMS(BUILD_STRING("sequence too big (" << e.what() << ")")));
 
373
  }
 
374
}
 
375
 
 
376
 
 
377
/*******************************************************************************
 
378
 
 
379
********************************************************************************/
302
380
void SimpleLazyTempSeqIter::open()
303
381
{
304
382
  theCurPos = theStartPos - 1;
305
383
}
306
384
 
307
385
 
 
386
/*******************************************************************************
 
387
 
 
388
********************************************************************************/
308
389
bool SimpleLazyTempSeqIter::next(store::Item_t& result)
309
390
{
310
391
  if (theCurPos < theEndPos && theTempSeq->containsItem(xs_integer(theCurPos+1)))
320
401
}
321
402
 
322
403
 
 
404
/*******************************************************************************
 
405
 
 
406
********************************************************************************/
323
407
void SimpleLazyTempSeqIter::reset()
324
408
{
325
409
  theCurPos = theStartPos - 1;
326
410
}
327
411
 
328
412
 
 
413
/*******************************************************************************
 
414
 
 
415
********************************************************************************/
329
416
void SimpleLazyTempSeqIter::close()
330
417
{
331
418
}